同步方法不起作用,但同步块起作用,为什么


public class driver{

public static void main(String[] args) {
PrintNum firstObjectForThread = new PrintNum(0);  // the argument is not used, ignore it
firstObjectForThread.startNewThread();
PrintNum secondObjectForThread = new PrintNum(0);
secondObjectForThread.startNewThread();
}

这是驱动程序调用的类:

public class ClassName implements Runnable{
int variableForUpdate;
private Thread t;
private static ArrayList<Integer> intArray;
public ClassName(int variableForUpdate) {
super();
this.intArray = new ArrayList<Integer>();
this.variableForUpdate = variableForUpdate;
for (int i = 0; i < 30 ; i++) {
this.intArray.add(i);
}
}
@Override
public void run() {
runThisWhenThreadStarts();
}

private synchronized void runThisWhenThreadStarts() {
System.out.println("Started");
for (int i = 0; i < 30; i++) {
System.out.println(intArray.get(i));
}
}
public void startNewThread() {
t = new Thread(this);
t.start();
}
}

如果我使用以下块同步,输出是同步的:

private void runThisWhenThreadStarts() {
synchronized (ClassName.class) {
System.out.println("Started");
for (int i = 0; i < 30; i++) {
System.out.println(intArray.get(i));
}
}
}

我已经解决这个问题好几个小时了,无法理解。。。有人能放些光吗?我还注意到,如果我使用同一个对象来调用startNewThread((,那么同步就会起作用。但我不明白为什么。

PrintNum firstObjectForThread = new PrintNum(0);  // the argument is not used, ignore it
firstObjectForThread.startNewThread();
firstObjectForThread.startNewThread();

我想使用同一类中的两个不同对象,而不是一个对象两次调用该方法(上面的解决方法(。

我能够在另一个程序中使用同步的方法,有两个不同的实例(get和put(:

public class Hello extends Thread {
int x;
Coffee x1;
int threadno;
Hello(int x, Coffee x1) {
this.x = x;
threadno = x;
this.x1 = x1;
}
public void run() {
switch (x) {
case 0:
System.out.println("Start thread " + threadno + " Get");
break;
case 1:
System.out.println("Start thread " + threadno + " Put");
break;
}
ops();
System.out.println("Stopping thread " + threadno);
}
public void ops() {
x1.get();
}
public static void main(String[] args) {
Coffee c1 = new Coffee();
Hello get = new Hello(0, c1);
Hello put = new Hello(0, c1);
get.start();
put.start();
}
}

你好班将呼叫咖啡班:

class Coffee {
boolean available = false; // indicating there nothing to get.
// waiting on each other.
int contents = 55;
public synchronized int get() {
System.out.println("Entering Get method " + contents);
for (int i = 0; i < 30; i++) {
System.out.println(i);
}
return contents;
}
}

在第一个例子中,方法获取调用该方法的对象实例的锁。块没有这样做,而是获取类的锁。

获取实例上的锁对其他线程没有影响,它是一个不同的对象。两个线程都在获取自己的锁,这是没有用的。两个线程都无法执行任何操作。

获取类上的锁意味着两个线程都试图获取相同的锁。要使锁工作,两个线程必须使用相同的锁。

在第二个示例中,Coffee对象由两个线程共享,并且两个线程都试图获取Coffee目标上的相同锁。这意味着要到达锁的第二个线程必须阻塞,直到第一个线程释放锁,锁定成功地将线程保持在外,直到完成第一个线程。

要理解同步,请跟踪正在获取的锁。

最新更新