在等待()之前调用Java notify()
另一个线程中的notify()不可能在一个线程中的wait()之前被调用吗? 这件事发生在我身上 客户端从目标请求一个值,并等待结果变量RV。 如果目标是客户机本身,我将使用正确的结果更新RV,并在另一个线程中对RV调用notify()在等待()之前调用Java notify(),java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,另一个线程中的notify()不可能在一个线程中的wait()之前被调用吗? 这件事发生在我身上 客户端从目标请求一个值,并等待结果变量RV。 如果目标是客户机本身,我将使用正确的结果更新RV,并在另一个线程中对RV调用notify() class EMU { ResultVar RV; Address my_address; ResultVar findValue(String key) { String tgt = findTarget(key); sendR
class EMU {
ResultVar RV;
Address my_address;
ResultVar findValue(String key) {
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV) {
RV.wait();
}
return RV;
}
Runnable Server = new Runnable() {
public void run() {
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0) {
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
RV.notify();
}
}
}
};
}
问题在于,在请求者自己完成所有“联网”(上例中为sendReqest)之前,结果会在结果变量中更新。当请求者线程现在调用wait()时,程序不会继续,因为已经调用了notify
我们如何防止它呢?如果在等待之前(在循环中)检查一些标志,请参阅教程:对于没有被另一个线程
等待的对象,没有任何东西可以阻止您调用notify
class EMU {
ResultVar RV;
Address my_address;
ResultVar findValue(String key) {
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV) {
RV.wait();
}
return RV;
}
Runnable Server = new Runnable() {
public void run() {
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0) {
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
RV.notify();
}
}
}
};
}
听起来,只有在某些条件成立时,您才需要等待。例如:
synchronized (results) {
while (!results.hasResults()) {
// no results yet; wait for them
try {
results.wait();
} catch (InterruptedException ie) { /* ignore */ }
}
}
我强烈建议不要重新发明轮子
Java的接口是为以后可能到达的结果而设计的,类实现了这个接口
让第一个线程访问未来,让第二个线程运行FutureTask,所有这些都会为您处理。您还可以免费获得超时支持。在转到wait()之前使用一些条件,并确保该条件是线程安全的:)
首先让我将代码分解为可复制的最小值:
public static void main(String[] args) throws Exception {
Object RV = new Object();
new Thread() {
@Override
public void run() {
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
RV.wait();
}
}
这种方法理论上永远不会结束,程序也永远不会退出。如果这是一个僵局,这将是一个争议
我的解决方案是创建第二个锁:
public static void main(String[] args) throws Exception {
Object RV = new Object();
Object lock = new Object();
new Thread() {
@Override
public void run() {
synchronized (lock) {
lock.wait();
}
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
synchronized (lock) {
lock.notify();
}
RV.wait();
}
}
让我们检查主线程等待一秒钟时线程正在执行的操作:
自定义线程将首先加入synchronized(lock)
块
然后锁将导致自定义线程等待
1秒后,主线程连接RV同步
锁会得到通知,并使自定义线程继续工作
自定义线程将保持同步(锁定)
块
主螺纹将处于RV等待锁定状态
自定义线程通知RV锁继续
程序结束。如果目标是客户机本身
这是什么意思?你能放一些代码样本吗?@shishir garg你能在没有看到代码的情况下粘贴一些代码吗?很难回答-2条评论:a)通常使用notifyAll比notify更好,除非您知道自己在做什么b)使用wait和notify可能容易出错,并且您应该使用更高级别的并发API,除非您需要非常具体的东西。