为什么同步在第二个代码中不起作用?
Why does synchronization not work in the second code?
同步在此代码中正常工作:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(PrintNumbers printNumbers, String s) {
this.printNumbers = printNumbers;
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
PrintNumbers printNumbers = new PrintNumbers();
new MyThread(printNumbers, "My Thread 1");
new MyThread(printNumbers, "My Thread 2");
}
}
输出:
in display
Thread name : My Thread 1 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 1 i= 2
out of display
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
out of display
但不在此代码中:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(String s) {
this.printNumbers = new PrintNumbers();
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
new MyThread("My Thread 1");
new MyThread("My Thread 2");
}
}
输出:
in display
Thread name : My Thread 1 i= 0
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
Thread name : My Thread 1 i= 2
out of display
out of display
我无法理解在 Runnable MyThread 和 SyncExample class 中初始化 PrintNumbers 与同步有什么不同。请解释。
因为在第二个代码中,每个线程都有自己的 PrintNumbers
对象,所以它们是并行工作的。在第一个中,他们共享单个 PrintNumbers
对象并以同步方式使用它。
PS。
请记住,非静态方法的 synchronized
在对象上进行同步(对于 class 上的静态方法)。
它在这两种情况下都能正常工作。不同之处在于,在第一种情况下,您只有一个同步的对象。在第二个中你有两个。它们都只被调用一次,所以它们是完美同步的。
synchronized
在对象之间不起作用,仅在一个对象内起作用。
I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class.
没有。 重要的是,在您的第一个示例中,您只有 one PrintNumbers
两个线程共享的实例。但是在第二个示例中,您有两个单独的 PrintNumbers
实例,每个线程一个。
由于PrintNumbers#display
在实例上同步(synchronized
实例方法在this
上同步),它只在实例内同步,而不是跨多个实例同步。
当两个线程共享一个实例时,对 display
的两次调用被序列化。但是当每个线程都有自己的实例时,对 display
的两次调用在不同的实例上,因此没有调用序列化,它们可以重叠。
同步在此代码中正常工作:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(PrintNumbers printNumbers, String s) {
this.printNumbers = printNumbers;
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
PrintNumbers printNumbers = new PrintNumbers();
new MyThread(printNumbers, "My Thread 1");
new MyThread(printNumbers, "My Thread 2");
}
}
输出:
in display
Thread name : My Thread 1 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 1 i= 2
out of display
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
out of display
但不在此代码中:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(String s) {
this.printNumbers = new PrintNumbers();
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
new MyThread("My Thread 1");
new MyThread("My Thread 2");
}
}
输出:
in display
Thread name : My Thread 1 i= 0
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
Thread name : My Thread 1 i= 2
out of display
out of display
我无法理解在 Runnable MyThread 和 SyncExample class 中初始化 PrintNumbers 与同步有什么不同。请解释。
因为在第二个代码中,每个线程都有自己的 PrintNumbers
对象,所以它们是并行工作的。在第一个中,他们共享单个 PrintNumbers
对象并以同步方式使用它。
PS。
请记住,非静态方法的 synchronized
在对象上进行同步(对于 class 上的静态方法)。
它在这两种情况下都能正常工作。不同之处在于,在第一种情况下,您只有一个同步的对象。在第二个中你有两个。它们都只被调用一次,所以它们是完美同步的。
synchronized
在对象之间不起作用,仅在一个对象内起作用。
I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class.
没有。 重要的是,在您的第一个示例中,您只有 one PrintNumbers
两个线程共享的实例。但是在第二个示例中,您有两个单独的 PrintNumbers
实例,每个线程一个。
由于PrintNumbers#display
在实例上同步(synchronized
实例方法在this
上同步),它只在实例内同步,而不是跨多个实例同步。
当两个线程共享一个实例时,对 display
的两次调用被序列化。但是当每个线程都有自己的实例时,对 display
的两次调用在不同的实例上,因此没有调用序列化,它们可以重叠。