1,使用注意事项
(1)三者的使用必须使用synchronized同步块,否则会报“java.lang.IllegalMonitorStateException”异常
(2)当线程A调用wait()方法后,在下一个时间点上线程A被唤醒了,会在wait()的下一行开始继续执行代码
2,原因
(1)必须使用同步块的原因是,wait()涉及到锁得释放,nofity()唤醒等待该锁,都是涉及到锁的相关操作,因此,如果没有加上sycronized同步,就没有锁,就会报异常。
3,实验
(1)wait()/notify()没有加上同步块,报 IllegalMonitorStateException 异常
结果异常:
加上同步块即可
(2)wait()等待之后,下次执行开始的地方
package ThreadTest;
public class test1 {
private volatile int mark = 1;
public void print1(Runnable runnable) {
runnable.run();
mark = 2;
// notifyAll();
synchronized (this) {
notifyAll();
}
}
public void print2(Runnable runnable) throws InterruptedException {
while (mark != 2) {
// wait();
synchronized (this) {
System.out.println("print2 进入等待");
wait();
System.out.println("print2 解除等待");
}
}
runnable.run();
mark = 3;
synchronized (this) {
notifyAll();
}
}
public void print3(Runnable runnable) throws InterruptedException {
while (mark != 3) {
synchronized (this) {
wait();
}
}
runnable.run();
}
public static class RunableTest1 implements Runnable {
@Override
public void run() {
System.out.println("first");
}
}
public static class RunableTest2 implements Runnable {
@Override
public void run() {
System.out.println("second");
}
}
public static class RunableTest3 implements Runnable {
@Override
public void run() {
System.out.println("three");
}
}
public static void main(String[] args) throws InterruptedException {
int[] arra = {1, 2, 3};
int[] arra6 = {1, 3, 2};
int[] arra2 = {2, 1, 3};
int[] arra5 = {2, 3, 1};
int[] arra3 = {3, 2, 1};
int[] arra4 = {3, 1, 2};
test1 test1 = new test1();
for (int i : arra5) {
if (i == 1) {
new Thread(() -> test1.print1(new RunableTest1())).start();
} else if (i == 2) {
new Thread(() -> {
try {
test1.print2(new RunableTest2());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
} else {
new Thread(() -> {
try {
test1.print3(new RunableTest3());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
}
结果: