我对以下代码中的Vector是静态的几乎没有疑问。 1.删除静态示例
public class WaitAndNotify extends Thread {
private String info;
Vector aVector;
.
.
//same code as below over here
.
.
public static void main (String args []) {
Vector aVector =new Vector();
new WaitAndNotify("first", aVector).start();
new WaitAndNotify("second", aVector).start();
new WaitAndNotify("last", aVector).start();
}
输出仍然保持不变(同步)。为什么?如果Vector是非静态的,则每个线程都有自己的Vector副本。所以输出不应该同步。但它是。为什么呢?
2.如果代码如下:
public class WaitAndNotify extends Thread {
private String info;
static Vector aVector = new Vector();
public WaitAndNotify (String info) {
this.info = info;
}
.
.
//code
.
.
public static void main (String args []) {
new WaitAndNotify("first").start();
new WaitAndNotify("second").start();
new WaitAndNotify("last").start();
}
现在,如果我删除静态并使向量非静态,那么输出将不会同步。为什么这样?
实际代码:
import java.util.Vector;
public class WaitAndNotify extends Thread {
private String info;
static Vector aVector = new Vector();
public WaitAndNotify (String info, Vector aVector) {
this.info = info;
this.aVector = aVector;
}
public void doTheJob() {
synchronized ( aVector ) {
if ( info.equals("last") ) {
System.out.println(info + " is waking up ...");
aVector.notifyAll();
System.out.println(info + " done.");
} else {
System.out.println(info + " is waiting");
try {
aVector.wait();
} catch ( IllegalMonitorStateException e ) {
System.out.println(info +
": IllegalMonitorStateException");
} catch ( InterruptedException e ) {
System.out.println(info +
": InterruptedException");
}
System.out.println(info + " is awake!");
}
}
}
public void run () {
doTheJob();
}
public static void main (String args []) {
new WaitAndNotify("first", aVector).start();
new WaitAndNotify("second", aVector).start();
new WaitAndNotify("last", aVector).start();
}
}
答案 0 :(得分:0)
在两种情况下"同步"有效......正在使用一个矢量对象!
赞:如果aVector
是静态的,则WaitAndNotify类的所有对象都会看到相同的对象引用。在另一种情况下,您将向三个实例提供相同矢量对象。
但是当你放弃静态时,WaitAndNotify的每个对象都在创建自己的向量,那么它们都使用不同的向量对象。
猜猜当三个不同的线程锁定三个不同的锁时会发生什么......确切地说:没有同步。这就是锁定的重点 - 确保这些线程有共同点;否则线程存在于他们自己的宇宙中,没有任何"连接"到其他线程。
答案 1 :(得分:0)
在两个代码示例中,只有一个向量,所有线程都有一个引用。
从第二个例子开始:你有一个静态变量,所以它被所有WaitAndNotify
个实例共享。
在第一个代码示例中,您创建一个向量(使用Vector aVector =new Vector();
)并将其引用传递给每个线程。传递引用不会复制矢量,也不会创建新的矢量。如果要为每个线程创建新向量,则必须按如下方式修改代码:
new WaitAndNotify("first", new Vector()).start();
new WaitAndNotify("second", new Vector()).start();
new WaitAndNotify("last", new Vector()).start();
上面,创建了三个单独的向量(有三个new Vector()
调用),因此每个线程都有自己的向量实例。
请注意,如果所有线程都有自己的向量(并且不要将其共享给其他线程),那么您就不需要同步,Vector
类自己提供同步。因此,您可以使用不同的数据结构,例如ArrayList
,它没有同步,因此可能会更快一些。