Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块。同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁。synchronized
关键字可以作用于
当一个方法或代码块被声明为synchronized时,如果一个线程正在执行该synchronized 方法或代码块,其他线程会被阻塞,直到持有同步锁的线程释放。根据锁定的范围可以分为
对象级别的同步锁:当我们想要在多线程环境下同步执行一个非静态方法或非静态代码块时,在类的方法或代码块加上synchronized关键字,可以保证对象实例级别数据的线程安全。(比较后文的类级别的同步锁,回头来理解这句话)
对象级别的加锁的代码如下,如:在方法上加锁,锁对象为当前类的实例化对象
public class DemoClass{
public synchronized void demoMethod(){}
}
如:为代码块加锁,锁对象为this对象
public class DemoClass{
public void demoMethod(){
synchronized (this){
//同步代码块
}
}
}
如:为代码块加锁,锁对象为我们创建的任意一个对象。不要使用非final的成员变量作为同步锁对象,因为非final成员变量可以被重新赋值,导致不同的线程使用不同的对象作为锁,达不到同步锁定的效果。
public class DemoClass{
//注意这里的关键字final非常重要,看说明
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock){
//同步代码块
}
}
}
类级别的锁可以防止多个线程在运行时进入该类所有实例化对象的 "synchronized块中。也就是说如果运行时有100个DemoClass
的实例,那么每次只有一个线程能够在任何一个实例中执行demoMethod()
,所有其他实例的所有其他线程都被锁定。
为了保障静态数据线程安全,应该使用类级别的锁定。我们知道static关键字将方法的数据关联到类的级别上,所以在静态方法上使用锁。
静态方法加锁,对该类所有的实例化对象生效
public class DemoClass{
//静态方法加锁,对该类所有的实例化对象生效
public synchronized static void demoMethod(){
}
}
获取 .class类的引用,类级别的锁
public class DemoClass{
public void demoMethod(){
//获取 .class类的引用,类级别的锁,对该类所有的实例化对象生效
synchronized (DemoClass.class){
//同步代码块
}
}
}
使用静态对象的锁,类级别的锁
public class DemoClass{
//静态对象,类级别,注意这里的关键字final非常重要
private final static Object lock = new Object();
public void demoMethod(){
//使用静态对象的锁,类级别锁,对该类所有的实例化对象生效
synchronized (lock){
//同步代码块
}
}
}
synchronized
方法或代码块时,它就会获得一个锁,当它离开同步方法或代码块时,它就会释放这个锁。如果线程执行过程出现任何错误或异常,锁也会被释放。synchronized
同步方法会给你的应用程序带来性能成本。因此,尽量在绝对需要的情况下才使用同步。另外优先考虑使用同步代码块,并且只同步代码的关键部分。synchronized
关键字。这是不合法的,会导致编译错误。不要使用字符串字面量作为锁对象,如:String a = "1";
,因为它们可能会被应用程序中的其他地方引用,并可能导致死锁。用new
关键字创建的字符串对象可以安全使用。
本文转载注明出处(必须带连接,不能只转文字):字母哥博客 - zimug.com
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
本文在研究了使用非对称加密保障数据安全的 技术基础 上,使用 NodeJS 作为服务...
dreamweaver中可以失踪一些鼠标经过的效果,今天我们就来看看dw制作鼠标经过图片...
性能真的很重要吗? 性能很重要,这个大家都知道。为什么我们还要做出速度很慢的...
计时器 (Timer)可以制作 WML 卡片来使用 WML 的计时器功能。计时器的时间单位是...
媒体设备类型使用详解: !DOCTYPE htmlhtml lang=enhead meta charset=UTF-8 tit...
开启全站 https 访问以来,分享代码一直不能用,启用了小绿标就成了灰标。唉,为...
meta http-equiv=X-UA-Compatible content=IE=7 / 以上代码告诉IE浏览器,无论是...
Bit-map的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素...
Dreamweaver插入网页中的图片大小不合适,想要裁剪图片,该怎么裁剪并编辑图片呢...
加了junit单元测试后出现如下报错 解决方法: resources 文件夹下新建 log4j.pro...