Java wait() 和 notify() 无法正常工作
Java wait() and notify() not working properly
我是 Java 多线程的新手,我遇到了一个问题。
public class WaitAndNotify {
private static List<String> strings = Collections.synchronizedList(new ArrayList<>());
public static void main(String[] args) {
new Operator().start();
new Machine().start();
}
// Operator thread
static class Operator extends Thread {
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Operator is working");
synchronized (strings) {
strings.add(scanner.nextLine());
strings.notify();
System.out.println("Notifying to machine");
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// Machine thread
static class Machine extends Thread {
@Override
public void run() {
while (strings.isEmpty()) {
synchronized (strings) {
try {
strings.wait();
System.out.println("Machine is waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(strings.remove(0));
}
}
}
}
}
我有操作员和机器threads
。我启动每个线程,当我在控制台中写东西时,它必须 notify
机器并且机器必须打印它。那行得通,但有时机器不打电话。当我删除 notify
之后的 thread.sleep()
部分时,它根本不起作用。
一切正常时的控制台。
Operator is working
Hi... // That's our message that we write in console
Notifying to machine
Machine is waiting
Hi... // Machine printed our message successfully after 1 second
Operator is working
如果删除 thread.sleep()
部分会怎样。
Operator is working
Hi... // That's our message that we write in console
Notifying to machine
Operator is working
如您所见,机器不工作。我不知道也许它被锁定了或别的什么。那么谁能向我解释为什么当 thread.sleep()
被删除时机器不打印我们的消息?
当你移除睡眠时,机器必须等到
之后的锁被释放
System.out.println("Notifying to machine");
在那条线之后,机器和操作员都在争夺锁。如果操作员击败机器,那么它会在机器打印任何内容之前第二次要求输入。在这一点之后,机器将只能打印一次,然后退出 while 循环。因为它只从数组中删除 1 个元素,所以数组总是有超过 0 个元素。
以下版本工作正常
static class Operator extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Operator is working");
synchronized (strings) {
System.out.println("Notifying to machine1");
strings.add(scanner.nextLine());
strings.notify();
System.out.println("Notifying to machine2");
try {
strings.wait();
}catch (Exception ex){}
}
}
}
}
// Machine thread
static class Machine extends Thread {
@Override
public void run() {
while (strings.isEmpty()) {
System.out.println("strings is empty");
synchronized (strings) {
strings.notify();
try {
System.out.println("Machine is waiting 1");
strings.wait();
System.out.println("Machine is waiting 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(strings.remove(0));
}
}
}
}
我是 Java 多线程的新手,我遇到了一个问题。
public class WaitAndNotify {
private static List<String> strings = Collections.synchronizedList(new ArrayList<>());
public static void main(String[] args) {
new Operator().start();
new Machine().start();
}
// Operator thread
static class Operator extends Thread {
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Operator is working");
synchronized (strings) {
strings.add(scanner.nextLine());
strings.notify();
System.out.println("Notifying to machine");
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// Machine thread
static class Machine extends Thread {
@Override
public void run() {
while (strings.isEmpty()) {
synchronized (strings) {
try {
strings.wait();
System.out.println("Machine is waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(strings.remove(0));
}
}
}
}
}
我有操作员和机器threads
。我启动每个线程,当我在控制台中写东西时,它必须 notify
机器并且机器必须打印它。那行得通,但有时机器不打电话。当我删除 notify
之后的 thread.sleep()
部分时,它根本不起作用。
一切正常时的控制台。
Operator is working
Hi... // That's our message that we write in console
Notifying to machine
Machine is waiting
Hi... // Machine printed our message successfully after 1 second
Operator is working
如果删除 thread.sleep()
部分会怎样。
Operator is working
Hi... // That's our message that we write in console
Notifying to machine
Operator is working
如您所见,机器不工作。我不知道也许它被锁定了或别的什么。那么谁能向我解释为什么当 thread.sleep()
被删除时机器不打印我们的消息?
当你移除睡眠时,机器必须等到
之后的锁被释放System.out.println("Notifying to machine");
在那条线之后,机器和操作员都在争夺锁。如果操作员击败机器,那么它会在机器打印任何内容之前第二次要求输入。在这一点之后,机器将只能打印一次,然后退出 while 循环。因为它只从数组中删除 1 个元素,所以数组总是有超过 0 个元素。
以下版本工作正常
static class Operator extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Operator is working");
synchronized (strings) {
System.out.println("Notifying to machine1");
strings.add(scanner.nextLine());
strings.notify();
System.out.println("Notifying to machine2");
try {
strings.wait();
}catch (Exception ex){}
}
}
}
}
// Machine thread
static class Machine extends Thread {
@Override
public void run() {
while (strings.isEmpty()) {
System.out.println("strings is empty");
synchronized (strings) {
strings.notify();
try {
System.out.println("Machine is waiting 1");
strings.wait();
System.out.println("Machine is waiting 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(strings.remove(0));
}
}
}
}