Java 为什么多个线程能够访问同步块?
在运行此命令时,我得到了Java 为什么多个线程能够访问同步块?,java,multithreading,synchronized,illegalmonitorstateexcep,Java,Multithreading,Synchronized,Illegalmonitorstateexcep,在运行此命令时,我得到了IllegalMonitorStateException,因为即使是线程也试图在对象上没有锁时发出通知isEven。为什么会这样?如果线程在对象上具有锁,那么它应该只能进入同步块内部 public class NumPrinter implements Runnable{ public static Boolean isEven = true; private boolean isEvenThread; private int i; p
IllegalMonitorStateException
,因为即使是线程也试图在对象上没有锁时发出通知isEven
。为什么会这样?如果线程在对象上具有锁,那么它应该只能进入同步块内部
public class NumPrinter implements Runnable{
public static Boolean isEven = true;
private boolean isEvenThread;
private int i;
public void run() {
while(i < 100){
synchronized(isEven){
boolean notPrinting = (isEven ^ isEvenThread);
System.out.println(notPrinting);
if(notPrinting) {
try {
isEven.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(i + ",");
i = i+2;
isEven = !isEven;
isEven.notifyAll();
}
}
}
public NumPrinter(boolean isEvenThread) {
this.isEvenThread = isEvenThread;
if(isEvenThread)
i = 0;
else
i = 1;
}
}
public class MultiThreading {
public static void main(String[] args) {
Thread oddt = new Thread(new NumPrinter(false), "Odd");
Thread event = new Thread(new NumPrinter(true), "Even");
event.start();
oddt.start();
}
}
公共类NumPrinter实现可运行{
公共静态布尔值isEven=true;
私有布尔线程;
私人互联网i;
公开募捐{
而(i<100){
已同步(isEven){
布尔notPrinting=(isEven^isEvenThread);
系统输出打印项次(不打印);
如果(不打印){
试一试{
等一等;
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印(i+“,”);
i=i+2;
isEven=!isEven;
isEven.notifyAll();
}
}
}
公共NumPrinter(布尔isEvenThread){
this.isEvenThread=isEvenThread;
如果(IsEventThread)
i=0;
其他的
i=1;
}
}
公共类多线程{
公共静态void main(字符串[]args){
螺纹oddt=新螺纹(新NumPrinter(假),“奇数”);
线程事件=新线程(新NumPrinter(true),“偶数”);
event.start();
oddt.start();
}
}
我不是Java专家,但您可以在此处重写同步令牌:
我甚至=!伊塞文
这可能不是您遇到的唯一问题,但至少使用另一个同步令牌(不会被重写)。您可能需要对常量对象进行同步/等待/通知。还将
isEven
声明为易失性。最后,将wait()
调用放入循环,检查循环条件,作为正式文档:
公共类NumPrinter实现可运行{
私有静态最终对象监视器=新对象();
私有静态可变布尔值isEven=true;
私有最终布尔线程;
私人互联网i;
@凌驾
公开募捐{
而(i<100){
同步(监视器){
while(isEven^isEvenThread){
试一试{
monitor.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印(i+“,”);
i=i+2;
isEven=!isEven;
monitor.notifyAll();
}
}
}
...
}
似乎您正在做与…相同的作业注意:同步的目的不是阻止两个线程同时执行相同的代码。它的目的是防止两个线程同时访问相同的数据。这是我试图说的扩展和精确版本。回答得好,伙计。
public class NumPrinter implements Runnable {
private static final Object monitor = new Object();
private static volatile boolean isEven = true;
private final boolean isEvenThread;
private int i;
@Override
public void run() {
while (i < 100) {
synchronized (monitor) {
while (isEven ^ isEvenThread) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(i + ",");
i = i + 2;
isEven = !isEven;
monitor.notifyAll();
}
}
}
...
}