在synchronized方法中修改后,所有java线程是否会看到共享资源更新?

RTF*_*RTF 7 java concurrency

Collections如果对一对数据结构的所有访问总是包含锁的获取和释放(特别是使用静态同步方法进行任何修改),是否有必要使用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
}
Run Code Online (Sandbox Code Playgroud)

我知道synchronized方法一次只执行一个线程执行更新,但是当一个线程退出该方法时,其他线程是否保证看到更新的数据结构,或者我是否还需要专门的并发数据结构那保证?

编辑:

这是我正在尝试做的更好的例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

Sim*_*ann 6

是的,如果访问始终包含在同步的方法/块中.

这是因为,synchronized 在同步的方法/块之间建立了一个先发生的关系(在同一个对象上).引用Java教程中的同步方法:

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立先发生关系.这可以保证对所有线程可以看到对象状态的更改.

但是,真正将所有访问权限包装在同步块中非常重要.例如,如果您愿意从这样的同步方法返回对列表的引用

public synchronized List<Object> GetList() {
    return this.myList;
}
Run Code Online (Sandbox Code Playgroud)

并使用synchronized方法之外的列表,您将无法获得该保证!