Java wait()和notify()工作不正常
我是Java多线程方面的新手,我遇到了一个问题Java wait()和notify()工作不正常,java,multithreading,java-threads,Java,Multithreading,Java Threads,我是Java多线程方面的新手,我遇到了一个问题 public class WaitAndNotify { private static List<String> strings = Collections.synchronizedList(new ArrayList<>()); public static void main(String[] args) { new Operator().start(); new Machine
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));
}
}
}
}
}
如果删除了thread.sleep()
部分,会发生什么情况
Operator is working
Hi... // That's our message that we write in console
Notifying to machine
Operator is working
正如你们所看到的,机器不工作了。我不知道可能是锁上了还是别的什么。所以,有人能向我解释一下,当
thread.sleep()
被删除时,机器为什么不打印我们的消息吗?当您删除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));
}
}
}
}
操作员只是在等待输入。确实有更好、更高级的方法来实现同步。我建议使用
阻塞队列
,它基本上可以免费提供您想要的行为。如果没有睡眠,操作员可以多次获得锁,而不给机器一个机会。如果发生这种情况,数组将至少有2个元素。如果机器获得锁,它将打印一次,然后返回,因为而(strings.isEmpty())
将返回false确定谢谢。我懂一点,但不完全懂
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));
}
}
}
}