gpt4 book ai didi

java - 如果我只想要一种在线程之间发出信号的方法,为什么我在哪个对象上使用 wait()/notify() 很重要?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:09:43 24 4
gpt4 key购买 nike

所以我有一个经典案例“我的代码有效,但我不知道为什么”。

我有一个创建线程的程序,当我从扫描器接收到特定输入时,我将字符串的控制权传递给工作线程。为此,我让我的线程等待 (),当我从我的 UI 线程获得正确的输入时,我通知 ()。

这是我的代码。为简单起见,我只使用了一个线程。

package main;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;


class ThreadDemo extends Thread {
private Thread t;
private String threadName;
volatile Boolean keepRunning = true;
private Queue<String> q = new LinkedList<String>();


ThreadDemo( String name){
threadName = name;
System.out.println("Creating " + threadName );
}

public void in(String ex){
q.add(ex);
System.out.println("Added " + ex + "to queue of " + threadName);
synchronized(t){
t.notify();
}
}


public void run() {
System.out.println("Starting to loop.");
while (keepRunning) {
try {
//Why does it matter that I synchronized t?
synchronized(t){
System.out.println(threadName + "Waiting");
t.wait();
}
} catch (InterruptedException e) {
System.out.println("Thread interrupted " + e.toString());
}
System.out.println(threadName + "notified");
if (q.size()>0){
String out = q.remove();
System.out.println(threadName + "received " + out);
}
}
System.out.println("Done looping.");
}

public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}


public class DataAnalysisProgram {

public static void main(String[] args) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();

System.out.println("say something");
Scanner s = new Scanner(System.in);
String t;
do{
t = s.next();
T1.in(t);
}while (!t.equals("stop"));

T1.keepRunning = false;
T1.interrupt();
s.close();
}
}

所以这很好用。我的线程一直等到我使用通知。但是,我真的不明白我在哪个对象上调用 notifywait 的意义。

在我的实现中,我随意地执行了 t.wait()/t.notify(),其中 t 是我的线程对象。我想如果我执行 threadName.wait()/threadName.notify() 它仍然有效。为什么我们要在看似任意的对象上调用 notify 和 wait?我知道我在这里遗漏了一个关于通知和等待的概念。

最佳答案

事实上,当您在 Thread 实例上调用 wait 时,您违反了契约:

It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

这是因为 Thread 将其用于其内部目的。

回答您的问题:Thread 对象不是线程。说 t.notify() 不通知 t,它通知等待 t 监视器的线程。在此上下文中,Thread 的实例只是另一个 Java 对象,所有 Java 对象都有一个与之关联的监视器。

您建议使用 String threadName 的监视器是另一个坏主意,因为您无法控制字符串实例的生命周期,并且可能很容易践踏内部字符串的问题。

建议的做法是不要在线程协调中涉及任意对象的监视器,但更愿意为此使用 Object 的专用实例。这是由关注点分离原则的一般优势插入的。

关于java - 如果我只想要一种在线程之间发出信号的方法,为什么我在哪个对象上使用 wait()/notify() 很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26157606/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com