Java 2线程有2个不同的对象

时间:2018-01-31 13:36:18

标签: java multithreading

鉴于下面提到的代码并假设我们有两个不同的线程thread1,thread2以及类BCell的两个不同的对象p1和p2。 如果 thread1 执行p1.swap(p2) thread2 同时执行p2.swap(p1) 可能会出现什么问题? 我已经阅读了herehere,但它似乎没有帮助。

    class BCell {
         int value;
         public synchronized int getValue() {
                return value;
         }
         public synchronized void setValue(int i) {
                value=i;
         }
         public synchronized void swap(BCell x) {
                int temp = getValue();
                setValue(x.getValue);
                x.setValue(temp);
        }
   }

3 个答案:

答案 0 :(得分:2)

  

这是一个同步的实例方法:

  public synchronized void add(int value){
      this.count += value;
  }
     

请注意在方法声明中使用synchronized关键字。   这告诉Java该方法是同步的。

     

Java中的同步实例方法在   实例(对象)拥有该方法。

报价来源为here

这意味着当您调用p1.swap(p2)时,它会阻止p1在该实例上的任何其他同步块中使用,直到p1.swap(p2)完成。因此,在您的情况下,setValue(x.getValue);无法同时调用。

答案 1 :(得分:1)

p1和p2是两个不同的实例。因此,即使方法不同步,也不应出现竞争条件。

请注意,这三个是实例方法,并且您在实例锁上进行同步。 p1和p2也是两个不同的实例。因此,在这种情况下,您提出的同步方法不会发生任何变化。

答案 2 :(得分:0)

可能的问题是p1和p2都得到相同的值。如果t1在读取任何内容之前t1一直执行到setValue(x.getValue());会导致此问题,例如val1 = 5val2 = 3(根据线程定义变量,希望它有意义)

val1 = 5    val2 = 3

tmp1 = 5

val1 = 3

            tmp2 = 3

val2 = 3

            val2 = 3

            val1 = 3

其中thread1位于第一列,thread2位于第二列。

也许你可以写这样的东西?

class BCell {
    Semaphore writeLock = new Semaphore(1);
    int value;
    public int getValue() {
        return value;
    }
    public void setValue(int i) throws InterruptedException {
        writeLock.acquire();
        value=i;
        writeLock.release();
    }
    public void swap(BCell x) throws InterruptedException {
        writeLock.acquire();
        if(x.writeLock.tryAcquire(10, TimeUnit.MILLISECONDS)) {
            int temp = getValue();
            setValue(x.getValue());
            x.setValue(temp);
            x.writeLock.release();
        }
        else {
            writeLock.release();
            swap(x);
        }
        writeLock.release();
    }
}