多语言展示
当前在线:1436今日阅读:176今日分享:34

Java中的同步

线程间的通讯首要的方式就是对字段及其字段所引用的对象的共享访问。这种通信方式是及其高效的,但是也是导致了可能的错误:线程间相互干涉和内存一致性的问题。避免出现这两种错误的方法就是同步。线程间相互干扰描述了当多个线程访问共享数据时可能出现的错误。内存一致性错误描述的了共享内存可能导致的错误。同步方法(Synchronized method)描述了一种简单的可以有效防止线程间相互干扰及其内存一致性错误的方法。明锁及同步描述了一种更加通用的同步方法,以及同步是如何基于明锁而实现的。原子性描述了不能被其它线程干扰的操作。
方法/步骤
1

Counter类对象的操作貌似不可能出现这种“交错”,因为其中的两个关于c的操作都很简单,只有一条语句。然而,即使是一条语句也是会被VM翻译成多个步骤的。在这里,我们不深究VM具体上上面的操作翻译成了什么样的步骤。只需要知道即使简单的c++这样的表达式也是会被翻译成三个步骤的:1. 获取c的当前值。2. 对其当前值加1。3. 将增加后的值存储到c中。表达式c--也是会被按照同样的方式进行翻译,只不过第二步变成了减1,而不是加1。假定线程A中调用increment方法,线程B中调用decrement方法,而调用时间基本上相同。如果c的初始值为0,那么这两个操作的“交错”顺序可能如下:1. 线程A:获取c的值。2. 线程B:获取c的值。3. 线程A:对获取到的值加1;其结果是1。4. 线程B:对获取到的值减1;其结果是-1。5. 线程A:将结果存储到c中;此时c的值是1。6. 线程B:将结果存储到c中;此时c的值是-1。这样线程A计算的值就丢失了,也就是被线程B的值覆盖了。上面的这种“交错”只是一种可能性。在不同的系统环境中,有可能是B线程的结果丢失了,或者是根本就不会出现错误。由于这种“交错”是不可预测的,线程间相互干扰造成的缺陷是很难定位和修改的。

2

同步方法—————————————————————————————————————————————————————————————————————————————Java编程语言中提供了两种基本的同步用语:同步方法和同步语句。同步语句相对而言更为复杂一些,我们将在下一小节中进行描述。本节重点讨论同步方法。我们只需要在声明方法的时候增加关键字synchronized即可:public class SynchronizedCounter {    private int c = 0;    public synchronized void increment() {        c++;    }    public synchronized void decrement() {        c--;    }    public synchronized int value() {        return c;    }}

3

如果count 是SynchronizedCounter类的实例,设置其方法为同步方法将有一下两个效果:首先,不可能出现对同一对象的同步方法的两个调用的“交错”。当一个线程在执行一个对象的同步方式的时候,其他所有的调用该对象的同步方法的线程对会被挂起,直到第一个线程对该对象操作完毕。其次,当一个同步方法退出时,会自动与该对象的后续同步方法间建立“先后顺序”的关系。这就确保了对该对象的修改对其他线程是可见的。注意:构造函数不能为同步的——在构造函数前使用synchronized关键字将导致语义错误。同步构造函数是没有意义的。这是因为只有创建该对象的线程才能调用其构造函数。

5

public class MsLunch {    private long c1 = 0;    private long c2 = 0;    private Object lock1 = new Object();    private Object lock2 = new Object();    public void inc1() {        synchronized(lock1) {            c1++;        }    }    public void inc2() {        synchronized(lock2) {            c2++;        }    }}同步的重入回忆前面提到的:线程不能获取已经被别的线程获取的锁。单丝线程可以获取自身已经拥有的锁。允许一个线程能重复获得同一个锁就称为同步重入。它是这样的一种情况:在同步代码中直接或者间接地调用了还有同步代码的方法,两个同步代码段中使用的是同一个锁。如果没有同步重入,在编写同步代码时需要额外的小心,以避免线程将自己阻塞。

推荐信息