我正在学习java线程(同步和锁定),但不知怎的,我无法找到这两件事之间的区别。
// Two different instances of SyncExample
Thread a1 = new Thread(new SyncExample(), "A");
Thread b1 = new Thread(new SyncExample(), "B");
// Same instance is passed to both the threads
SyncExample syn = new SyncExample();
Thread a2 = new Thread(syn, "A");
Thread b2 = new Thread(syn, "B");
// I believe in total 4 stacks are built.
a1.start();
b1.start();
a2.start();
b2.start();
public class SyncExample implements Runnable {
Object obj = new Object();
@Override
public void run() {
this.myName();
}
private void myName() {
synchronized (obj) {
System.out.print("Define" + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
System.out.println(ex);
}
System.out.print("tly" + Thread.currentThread().getName());
}
System.out.println(" Maybe" + Thread.currentThread().getName());
}
}
public class SyncExample implements Runnable {
Object obj = new Object();
@Override
public void run() {
this.myName();
}
private void myName() {
synchronized (obj) {
System.out.print("Define" + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
System.out.println(ex);
}
System.out.print("tly" + Thread.currentThread().getName());
}
System.out.println(" Maybe" + Thread.currentThread().getName());
}
}
但问题在于我使用
运行此示例1 - 相同的参考输出是:
DefineAtlyA MaybeA
DefineBtlyB MaybeB
2 - 2个不同的实例:
DefineADefineBtlyAtlyB MaybeB
MaybeA
当我们将runnable目标传递给Thread类时,是否有人可以解释它的不同之处 1.同样的例子 2.不同的实例
答案 0 :(得分:2)
在您的代码中,当您传递两个不同的实例(SyncExample
类)时,每个实例都有自己的锁定对象(由变量obj
保存)。由于存在两个不同的锁定对象,每个线程获取一个锁并并行执行,从而导致线程A和B的交错输出(DefineADefineBtlyAtlyB MaybeB MaybeA
)。
当您传递相同的实例时,只有一个SyncExample
类的实例。因此,只有一个锁定对象的实例(由变量obj
持有)。因此,这个锁对象将在两个线程之间共享。由于这种共享,只有一个线程(比如T1)能够进入同步块;另一个线程(比如T2)会等到T1存在同步块。因此,在执行过程中,首先会看到线程A的所有print语句,然后是线程B的所有语句(DefineAtlyA MaybeA DefineBtlyB MaybeB
)。
如果我要概括一下:当你传递不同的实例时,只有静态变量会影响线程的并行执行,但是当你传递单个实例时,静态和类级别的变量(例如{{1}代码中的变量)会影响线程的并行执行。
答案 1 :(得分:1)
输出应该暗示你的差异。
当您将相同的SyncExample
传递给两个不同的线程时,只有其中一个线程能够获取obj
上的锁定并执行synchronized
块中的代码。
当您传入两个不同的SyncExample
个对象时,两个线程都可以同时执行,因为它们正在同步不同的对象。