0

我上课了

class A{

private int id =0;
   public void setMessageId(Message m) {
      synchronized(m) {
        m.setId(id++);
      }
   }
}

具有相同A类实例和不同消息实例的两个线程可以同时进入同步块并将相同的ID设置为不同的消息实例吗?

4

8 回答 8

3

是的。您需要在包含该id字段的对象(在本例中为“A”)或一些常见对象上进行同步。

于 2012-07-31T07:27:02.147 回答
2

是的。由于块是在消息上同步的,因此使用两个不同消息实例的两个线程可以同时进入同步块,并且都得到相同的 ID。

使方法同步,一切都会好起来的。或者使用 AtomicInteger。

于 2012-07-31T07:28:07.363 回答
0

如果只在 m 上同步,那么两个对象将能够修改 A 的同一个实例。您需要在存储值 id 的对象上进行同步。

于 2012-07-31T07:29:02.287 回答
0

当然,因为您在不同的对象上同步。

如果您为此目的所需要的一切,最好使用 java.util.concurrent AtomicInteger来生成 ID 。

例如像这样:

private AtomicInteger counter;

public int getNextUniqueIndex() {
    return counter.getAndIncrement();
}
于 2012-07-31T07:29:17.907 回答
0

显然,因为锁是打开的 Message m,如果两个线程有​​不同的实例,Message那么它们可以..

于 2012-07-31T07:31:09.860 回答
0

1.由于同步锁是在 message 的实例上,那么两个不同 message 对象的线程肯定可以同时访问这个块。

2.即使他们设置了相同的实例变量,它就像一个个人副本,每个对象一个。

3.线程改变一个对象的变量 不会影响另一个对象的idid 。

于 2012-07-31T07:31:11.257 回答
0

是的:

锁定对象是为 m 对象获得的,它们是每个线程的 2 个不同对象,所以是的,它们可以。在您的情况下,您将需要获得一个在这两个和 A 类之间共享的锁。

于 2012-07-31T07:31:26.277 回答
0

是的,因为它们都有不同对象的锁。

完全没有自制同步的一种选择是使用AtomicInteger

class A{
    private final AtomicInteger id = new AtomicInteger();

    public void setMessageId(Message m) {
       m.setId(id.incrementAndGet());    
    }
}

方法incrementAndGet将值加一并返回更新后的值。

于 2012-07-31T07:32:23.330 回答