我上课了
class A{
private int id =0;
public void setMessageId(Message m) {
synchronized(m) {
m.setId(id++);
}
}
}
具有相同A类实例和不同消息实例的两个线程可以同时进入同步块并将相同的ID设置为不同的消息实例吗?
我上课了
class A{
private int id =0;
public void setMessageId(Message m) {
synchronized(m) {
m.setId(id++);
}
}
}
具有相同A类实例和不同消息实例的两个线程可以同时进入同步块并将相同的ID设置为不同的消息实例吗?
是的。您需要在包含该id
字段的对象(在本例中为“A”)或一些常见对象上进行同步。
是的。由于块是在消息上同步的,因此使用两个不同消息实例的两个线程可以同时进入同步块,并且都得到相同的 ID。
使方法同步,一切都会好起来的。或者使用 AtomicInteger。
如果只在 m 上同步,那么两个对象将能够修改 A 的同一个实例。您需要在存储值 id 的对象上进行同步。
当然,因为您在不同的对象上同步。
如果您为此目的所需要的一切,最好使用 java.util.concurrent AtomicInteger来生成 ID 。
例如像这样:
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
显然,因为锁是打开的 Message m
,如果两个线程有不同的实例,Message
那么它们可以..
1.由于同步锁是在 message 的实例上,那么两个不同 message 对象的线程肯定可以同时访问这个块。
2.即使他们设置了相同的实例变量,它就像一个个人副本,每个对象一个。
3.线程改变一个对象的变量 不会影响另一个对象的id
id 。
是的:
锁定对象是为 m 对象获得的,它们是每个线程的 2 个不同对象,所以是的,它们可以。在您的情况下,您将需要获得一个在这两个和 A 类之间共享的锁。
是的,因为它们都有不同对象的锁。
完全没有自制同步的一种选择是使用AtomicInteger:
class A{
private final AtomicInteger id = new AtomicInteger();
public void setMessageId(Message m) {
m.setId(id.incrementAndGet());
}
}
方法incrementAndGet将值加一并返回更新后的值。