想象一下,我们有多线程应用程序和一个具有以下变量和方法的类:
private List list = new ArrayList();
public void doNothing() {
synchronized (list) {
list.get(0);
String stuff = "Stuff";
list.get(0);
}
}
我是对的,当一个线程处理方法doNothing()
时,它会失去String stuff = "Stuff";
上的监视器而list.get(0);
的输出可能会有所不同,因为其他线程可以修改列表吗?
答案 0 :(得分:0)
是的,你是对的,但不是因为显示器在处理字符串时丢失了。您在列表上同步的事实不会阻止另一个线程更改它。在两个gets之间强制执行列表的唯一方法是让所有线程更改列表运行synchronized(list)中的代码。此外,拥有Synchronized list对您的情况无济于事。
答案 1 :(得分:0)
一次只能有一个线程可以在 synchronized 块中工作。但是,如果任何其他线程修改列表,例如某些其他函数,那么当然,list.get(0)的输出在调用之间可能不同。由于在此块中创建的字符串内容不能被当前正在运行它的任何其他线程更改。
答案 2 :(得分:0)
在同一监视器对象上同步的Java代码块中只能执行一个线程。
一旦线程到达同步块的末尾,线程只会“丢失监视器”。
在您的特定情况下,调用list.get(0)的结果;可以相同或不同,具体取决于可以在列表对象上同步的任何代码块之外调用该列表上的mutator的其他线程。
同步对象的目的是允许您在同一个锁上同步多个块。
在以下示例中,只有一个线程可以同时在两个块中的任何一个块内执行:
public void doNothing() {
synchronized (list) {
//someStuff
}
}
public void doSomething() {
synchronized (list) {
//anotherStuff
}
}