java 中的多个线程无法执行非同步代码
Multiple thread failed to execute the nonsynchronized code in java
如果 Thread1 获得锁并开始执行同步块,同时 Thread2 可以自由执行代码的非同步部分 IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name))
.
出乎意料,下面是我 运行 代码时实际发生的事情。
说明-
假设,thread1(或thread2)获得锁并执行synchronized块,然后thread2(或thread1)获得thread1(或thread2)释放的锁并执行synchronized block.After两个线程完成执行同步块,然后两个线程并行开始执行非同步部分。我 运行 代码多次希望获得所需的输出但没有用。
演示 class
public class Demo {
public static void main(String[] args) {
Display d=new Display("AnyName");
Thread1 t1=new Thread1(d);
Thread2 t2=new Thread2(d);
t1.start();
t2.start();
}
}
线程 1 class
public class Thread1 extends Thread {
Display d;
Thread1(Display d) {
this.d = d;
}
@Override
public void run() {
d.getname("Thread 1");
}
}
线程 2 class
public class Thread2 extends Thread {
Display d;
Thread2(Display d) {
this.d = d;
}
@Override
public void run() {
d.getname("Thread 2");
}
}
显示class
public class Display {
String name;
public Display(String name) {
this.name = name;
}
public void getname(String name) {
synchronized (this) {
IntStream.range(0, 5).forEach((idx) -> {
System.out.println(name);
});
this.name=name;
}
IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name));// this line
//get executed only after the synchronized method completed by both thread
}
}
输出:
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
如果Thread1拿到锁开始执行synchronized块,同时Thread2可以自由执行代码的非同步部分:不完全是。
在执行顺序上,非同步块在同步块之后。因此你永远不会看到任何线程在同步块之前执行非同步块。
你能期待的最好的事情就是
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
线程2进入同步块,线程1运行进入非同步块
您可以通过在同步块之后调用 Thread.yield();
并进行更多 System.out.println()
调用来更改 Display.getname()
方法,从而增加出现这种结果的机会:
public void getname(String name) {
synchronized (this) {
IntStream.range(0, 5).forEach((idx) -> {
System.out.println(name);
});
this.name=name;
}
Thread.yield();
IntStream.range(0, 20).forEach(x -> System.out.println("thread Unsafe Zone,"+name));
}
如果 Thread1 获得锁并开始执行同步块,同时 Thread2 可以自由执行代码的非同步部分 IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name))
.
出乎意料,下面是我 运行 代码时实际发生的事情。
说明-
假设,thread1(或thread2)获得锁并执行synchronized块,然后thread2(或thread1)获得thread1(或thread2)释放的锁并执行synchronized block.After两个线程完成执行同步块,然后两个线程并行开始执行非同步部分。我 运行 代码多次希望获得所需的输出但没有用。
演示 class
public class Demo {
public static void main(String[] args) {
Display d=new Display("AnyName");
Thread1 t1=new Thread1(d);
Thread2 t2=new Thread2(d);
t1.start();
t2.start();
}
}
线程 1 class
public class Thread1 extends Thread {
Display d;
Thread1(Display d) {
this.d = d;
}
@Override
public void run() {
d.getname("Thread 1");
}
}
线程 2 class
public class Thread2 extends Thread {
Display d;
Thread2(Display d) {
this.d = d;
}
@Override
public void run() {
d.getname("Thread 2");
}
}
显示class
public class Display {
String name;
public Display(String name) {
this.name = name;
}
public void getname(String name) {
synchronized (this) {
IntStream.range(0, 5).forEach((idx) -> {
System.out.println(name);
});
this.name=name;
}
IntStream.range(0, 5).forEach(x -> System.out.println("thread Unsafe Zone,"+name));// this line
//get executed only after the synchronized method completed by both thread
}
}
输出:
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
如果Thread1拿到锁开始执行synchronized块,同时Thread2可以自由执行代码的非同步部分:不完全是。
在执行顺序上,非同步块在同步块之后。因此你永远不会看到任何线程在同步块之前执行非同步块。
你能期待的最好的事情就是
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 1
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
thread Unsafe Zone,Thread 2
线程2进入同步块,线程1运行进入非同步块
您可以通过在同步块之后调用 Thread.yield();
并进行更多 System.out.println()
调用来更改 Display.getname()
方法,从而增加出现这种结果的机会:
public void getname(String name) {
synchronized (this) {
IntStream.range(0, 5).forEach((idx) -> {
System.out.println(name);
});
this.name=name;
}
Thread.yield();
IntStream.range(0, 20).forEach(x -> System.out.println("thread Unsafe Zone,"+name));
}