前言
在开发过程中经常会遇到多线程安全问题。 java提供了同步锁的关键字synchronized。 这很好地解决了多线程安全问题。 本章主要说明synchronized的使用方法和写法,让很多同学都不知道该怎么写。 如果有不理解的地方,谢谢您的指出。
一.同步锁定概念
对象锁定
对象锁定用于对象实例的方法或对象实例中
类锁定
类锁定用于类的静态方法或类的class对象
1.1什么是对象锁定
让我用代码解释一下
公共类用户{
privatestaticfinalstringtag=' user ';
权限对象o=new object (;
publicsynchronizedvoidupdatepwd (
log.d(tag,' updatePwd ' );
}
公共void更新用户名称(
同步(this ) {
log.d(tag,' updateUserName ' );
}
log.d(tag,' updateUserName2' );
}
public void deletePwd
同步(o ) {
log.d(tag,' deletePwd ' );
}
log.d(tag,' deletePwd2' );
}
从代码中可以看出,在上面添加了synchronized的3个函数都被称为对象时钟,可以有不同的3种写法
1.1.1第一类同步锁
在加载方法中,对函数整体进行锁定意味着在访问该函数时会带有锁定标记
publicsynchronizedvoidupdatepwd (
log.d(tag,' updatePwd ' );
}
1.1.2第二类同步锁
对同步块施加不同的对象锁定。 以下两种写法基本相同。 同步this是指将o锁定到当前user对象,而不是锁定到当前Object对象。 (这里需要注意。 此对象锁定只针对同一对象。 如果不同的对象互不影响,稍后将具体说明。 )以下格式与上面的不同之处在于,只同步函数中的某些代码,其他不同步。
公共void更新用户名称(
同步(this ) {
log.d(tag,' updateUserName ' );
}
log.d(tag,' updateUserName2' );
}
public void deletePwd
同步(o ) {
log.d(tag,' deletePwd ' );
}
log.d(tag,' deletePwd2' );
}
1.2什么类型的摇滚
以下两种表示法都称为类锁,它们是统一类对象的锁。 也就是说,用户1、用户2、用户3 .等在多线程访问时生效
公共类用户{
privatestaticfinalstringtag=' user ';
权限对象o=new object (;
publicstaticsynchronizedvoidclassupdatepwd (
log.d(tag,' classUpdatePwd ' );
}
公共语音类username ()
synchronized(user.class ) {
log.d(tag,' classUpdateUserName ' );
}
}
}
2 .同步在多线程中的作用和用法
2.1作用
由于一个块的共享数据可由多个线程同时访问和操作,因此共享数据对这些线程来说不是唯一的
2.2使用方法
2.2.1对象锁的使用方法
以下代码演示了多线程锁定同步同一对象的操作。 此时,如果updatePwd函数正在访问t1线程,则在t2线程进行访问时,在t1线程执行此函数并解除锁定之前无法访问。 这意味着在统一时间内,同一对象user的updatePwd资源只对同一线程操作,操作完成后再对另一个线程操作
publicstaticvoidmain (string [ ] args ) {
final User user=new User (;
//t1线程和t2线程调用了同一对象的updatePwd方法。 这里需要注意的是t1和t2的代码表示有前后关系,但在执行时t1并不一定会先被执行
threadT1=newthread(newrunnable () {
@Override
公共语音运行(}
user.updatePwd (;
}
);
t1.start (;
threadT2=newthread(newrunnable () {
@Override
公共语音运行(}
user.updatePwd (;
}
);
t2.start (;
}
2.2.2种锁的使用方法
这里与对象时钟的不同之处在于,与类时钟为同种的对象,例如User1、user2、user3为user的对象
publicstaticvoidmain (string [ ] args ) {
//t1线程和t2线程分别访问user1和user2的同名函数,在user1操作同名函数的期间,user2需要等待到user1的操作结束解除锁定为止
final User user1=new User (;
final User user2=new User (;
threadT1=newthread(newrunnable () {
@Override
公共语音运行(}
user1.classUpdatePwd (;
}
);
t1.start (;
threadT2=newthread(newrunnable () {
@Override
公共语音运行(}
user2.classUpdatePwd (;
}
);
t2.start (;
}
3 .总结
1。 在多线程中,对象锁定是用任何写法对统一对象进行的
2。 类锁定是针对同一类型的对象进行的,在多线程访问时,无论当前类的哪个实例对象占用了锁定,其他实例对象都必须等待
3。 以上说明的是访问同一函数名,但实际上其他函数也被锁定了。 是同样的原理。 例如,要访问Thread1对用户锁定的synchronized a (函数)和Thread2访问用户的synchronized b (函数),Thread1必须等待用户释放a锁