修饰方法
修饰非静态的方法
// 代码块1
public synchronized void method()
{
// todo
}
这种情况下是对象锁
tips:在定义接口方法时不能使用synchronized关键字。
修饰一个静态的方法
// 代码块2
public synchronized static void method() {
// todo
}
这种情况下是类锁,给当前类加锁。
修饰一个代码块
给this加锁
// 代码块3
public void method()
{
//锁定的对象为this
synchronized(this)
{
// todo
}
}
这种情况下是加对象锁,给当前对象加锁。和代码块1作用相似。是代码块4的特殊情况。
给某个对象加锁
// 代码块4
public void method(SomeObject obj)
{
//obj 锁定的对象
synchronized(obj)
{
// todo
}
}
这种情况下是加对象锁,给obj对象加锁
给类加锁
代码块5
class ClassName {
public void method() {
synchronized(ClassName.class) {
// todo
}
}
}
这种情况下是类锁,给ClassName类加锁。
特别说明
不能给静态代码块加锁
// 代码块6
class ClassName {
static synchronized(ClassName .class)
{
// todo
}
}
没有这种用法
一个对象只有一把锁
// 代码块7
public synchronized void method()
{
// todo 1
}
public void method2()
{
synchronized(this)
{
// todo 2
}
}
如果一个线程在执行todo1中,其他线程不仅不能访问todo1,也不能访问todo2。因为它们共用一把锁,即当前对象(this)的锁。
总结
-
无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象的锁;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是类的锁。
-
每个对象(某种意义上类也是一个对象)只有一个锁与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码 。
参考文章:
https://www.cnblogs.com/zyxiaohuihui/p/9096882.html
https://www.cnblogs.com/dolphin0520/p/3923167.html
https://blog.youkuaiyun.com/u011212394/article/details/82228321
https://blog.youkuaiyun.com/qa275267067/article/details/79804713
https://blog.youkuaiyun.com/sinat_32588261/article/details/72880159