首页 理论教育 同步代码块的使用方法,让Java程序设计更高效

同步代码块的使用方法,让Java程序设计更高效

时间:2023-11-16 理论教育 版权反馈
【摘要】:默认情况下标志位为1,此时线程会执行Synchronized 同步代码块,同时将锁对象的标志位置为0。同步代码块和同步方法解决多线程问题有好处也有弊端。文件11-11Example11.java执行结果通过11.5.2 小节的学习,了解到同步代码块可以有效解决线程的安全问题,当把共享资源的操作放在synchronized 定义的区域内时,便为这些操作加了同步锁。

同步代码块的使用方法,让Java程序设计更高效

通过11.5.1 小节学习,了解到线程安全问题其实就是由多个线程同时处理共享资源所导致的。要想解决文件11-10 中的线程安全问题,必须得保证下面用于处理共享资源的代码在任何时刻只能有一个线程访问。

为了实现这种限制,Java 中提供了同步机制。当多个线程使用同一个共享资源时,可以将处理共享资源的代码放在一个使用synchronized 关键字来修饰的代码块中,这个代码块被称作同步代码块,其语法格式如下:

在上面的代码中,lock 是一个锁对象,它是同步代码块的关键。当某一个线程执行同步代码块时,其他线程将无法执行当前同步代码块而发生阻塞,等当前线程执行完同步代码块后,所有的线程开始抢夺线程的执行权,抢到执行权的线程将进入同步代码块,执行其中的代码。循环往复,直到共享资源被处理完为止。这个过程就好比一个公用电话亭,只有前一个人打完电话出来后,后面的人才可以打。Synchronized 关键字后大括号{}内包含的就是需要同步操作的共享资源代码块。lock 锁对象可以是任意类型的对象,但多个线程共享的锁对象必须是相同的。锁对象的创建代码不能放到run()方法中,否则每个线程运行到run()方法都会创建一个新对象,这样每个线程都会有一个不同的锁。

原理:

(1)当线程执行同步代码块时,首先会检查lock 锁对象的标志位。

(2)默认情况下标志位为1,此时线程会执行Synchronized 同步代码块,同时将锁对象的标志位置为0。

(3)当一个新的线程执行到这段同步代码块时,由于锁对象的标志位为0,新线程会发生阻塞,等待当前线程执行完同步代码块后。

(4)锁对象的标志位被置为1,新线程才能进入同步代码块执行其中的代码,这样循环往复,直到共享资源被处理完为止。

注意:

同步方法也有锁,它的锁就是当前调用该方法的对象,就是this 指向的对象。Java 中静态方法的锁是该方法所在类的class 对象,该对象可以直接类名.class 的方式获取。同步代码块和同步方法解决多线程问题有好处也有弊端。同步解决了多个线程同时访问共享数据时的线程安全问题,只要加上同一个锁,在同一时间内只能有一条线程执行,但是线程在执行同步代码时每次都会判断锁的状态,非常消耗资源,效率较低。(www.xing528.com)

【例11.11】下面将文件11-10 中售票的代码放到synchronized 区域中,如文件11-11 所示。

文件11-11 Example11.java

执行结果

通过11.5.2 小节的学习,了解到同步代码块可以有效解决线程的安全问题,当把共享资源的操作放在synchronized 定义的区域内时,便为这些操作加了同步锁。在方法前面同样可以使用synchronized 关键字来修饰,被修饰的方法为同步方法,它能实现和同步代码块同样的功能,具体语法格式如下:

被synchronized 修饰的方法在某一时刻只允许一个线程访问,访问该方法的其他线程都会发生阻塞,直到当前线程访问完毕后,其他线程才有机会执行该方法。

【例11.12】下面使用同步方法对文件11-11 进行修改,如文件11-12 所示。

文件11-12 Example12.java

执行结果

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈