在同步方法中修改后,所有java线程都会看到共享资源更新吗?

在同步方法中修改后,所有java线程都会看到共享资源更新吗?,java,concurrency,Java,Concurrency,如果对一对数据结构的所有访问总是通过获取和释放锁来包装(特别是对数据结构的任何修改使用静态同步方法),那么是否有必要使用Java的集合的专用并发版本数据结构(例如CopyOnWriteArrayList vs ArrayList). 例如: public static synchronized Item doIt() { // remove something from data structure 1 // add the removed item to data struct

如果对一对数据结构的所有访问总是通过获取和释放锁来包装(特别是对数据结构的任何修改使用静态同步方法),那么是否有必要使用Java的
集合的专用并发版本
数据结构(例如CopyOnWriteArrayList vs ArrayList). 例如:

public static synchronized Item doIt() {
    // remove something from data structure 1
    // add the removed item to data structure 2
    // return removed item
}
我知道同步方法一次只能执行一个线程来执行更新,但是当一个线程退出该方法时,是否保证其他线程可以看到更新的数据结构,或者我仍然需要专门的并发数据结构来保证

编辑:

下面是一个更好的例子,说明我正在尝试做什么:

private static final List<Item> A;
private static final HashMap<Integer,Item> B;

public static Item doSomething() {
    // some stuff ...
    Item item = doIt();
    // some other stuff ...
    return item;
}

private static synchronized Item doIt() {
    Item theItem = A.remove( A.size()-1 );
    B.put( theItem.getId(), theItem );
    return theItem;
}
私有静态最终列表A;
私有静态最终HashMap B;
公共静态项doSomething(){
//一些东西。。。
Item=doIt();
//其他一些东西。。。
退货项目;
}
私有静态同步项doIt(){
项目ITEEM=A.移除(A.尺寸()-1);
B.put(item.getId(),item);
归还他们;
}

同步不仅仅是相互排斥。也就是说,它是关于在块内(以及在块之前)进行的所有操作对随后获得相同锁的任何其他线程的可见性

因此,当对结构的所有访问使用锁定时,不需要并发数据结构


最后,请确保:如果访问始终包装在同步方法/块中,则必须对所有访问(包括所有读取)使用锁定。

Yes

这是因为,synchronized在同步方法/块(在同一对象上)之间建立了“发生在之前”关系。引述自:

其次,当同步方法退出时,它会自动建立 与任何后续调用的关系之前发生 同一对象的同步方法。这保证了的变化 对象的状态对所有线程可见

但是,重要的是,您必须将所有访问包装在同步块中。例如,如果您想从以下同步方法返回对列表的引用

public synchronized List<Object> GetList() {
    return this.myList;
}
公共同步列表GetList(){
返回此.myList;
}

使用同步方法之外的列表,您将无法获得该保证

您不应该需要这样的集合,因为您正在手动执行锁定。但是为什么要重新发明轮子呢?@LuiggiMendoza因为你不能在不锁定的情况下以原子方式修改两个集合。@WilliamF.Jameson但是这些集合框架的并发版本已经有了这种锁定处理,并允许对它们进行原子操作。再说一遍:为什么要重新发明轮子?@LuiggiMendoza OP有两个系列。这两个更新作为一个整体不会是原子的。您是否总是从同一类中的
静态
同步
方法访问它们?只有始终在同一对象上同步时,同步才有帮助。你知道一个
静态
同步
方法同步的对象是什么吗?@RTF现在我想知道为什么它们都是
静态
。看起来您遇到的是设计问题,而不是多线程问题。