gst*_*low 2 java concurrency synchronization wait
我尝试了解java核心同步.
我写了代码示例:
程序应该写
左右
10倍
package concurrency;
public class LeftRightWaitNotifyExample {
final static String str = "1";
public static void main(String[] args) {
new LeftLegThread(str).start();
new RightLegThread(str).start();
}
}
class LeftLegThread extends Thread {
String monitor;
public LeftLegThread(String str) {
monitor = str;
}
@Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
for (int i = 0; i < 10; i++) {
System.out.println("Left ");
wait();
}
}
}
}
class RightLegThread extends Thread {
String monitor;
public RightLegThread(String str) {
monitor = str;
}
@Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Right ");
notify();
wait();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
Left
Right
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at concurrency.LeftLegThread.makeStep(LeftRightWaitNotifyExample.java:35)
at concurrency.LeftLegThread.run(LeftRightWaitNotifyExample.java:23)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at concurrency.RightLegThread.makeStep(LeftRightWaitNotifyExample.java:61)
at concurrency.RightLegThread.run(LeftRightWaitNotifyExample.java:51)
Run Code Online (Sandbox Code Playgroud)
在我wait在synchronized块内使用非方法时出现此错误之前.但在这里我使用内等待synchronized块
问题的原因是什么以及如何解决?
我根据建议改写代码:
public class LeftRightWaitNotifyExample {
final static String str = "1";
public static void main(String[] args) throws InterruptedException {
new LeftLegThread(str).start();
Thread.sleep(100);
new RightLegThread(str).start();
}
}
class LeftLegThread extends Thread {
String monitor;
public LeftLegThread(String str) {
monitor = str;
}
@Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
for (int i = 0; i < 2; i++) {
System.out.println("Left ");
monitor.wait();
monitor.notify();
}
}
}
}
class RightLegThread extends Thread {
String monitor;
public RightLegThread(String str) {
monitor = str;
}
@Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Right ");
monitor.notify();
monitor.wait();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
电流输出:
Left
Right
Left
Right
Right
Run Code Online (Sandbox Code Playgroud)
为什么Right出局3但Left只有两次.为什么?
你正在同步monitor,所以你也应该wait()在监视器上:
monitor.wait();
Run Code Online (Sandbox Code Playgroud)
现在你正在等待this,这不是监视器的所有者,因为同步已打开monitor.
请注意,当然notify也应该在monitor对象上完成,并且您可能要考虑在两个线程中使用notify/ .否则可能会发生一个线程饿死等待丢失通知.使用超时(重载版本)也可能是捕捉极端情况的好主意.notifyAllwait
| 归档时间: |
|
| 查看次数: |
8258 次 |
| 最近记录: |