Java 如何将更改通知正在运行的线程
我正在处理一个客户机/服务器项目,它监视服务器中的系统事件,并向客户机发送更改通知。它由一个监视者对象和一个服务器对象组成,前者负责监视,后者为连接到它的每个客户端创建线程。考虑到下面的简化代码(我包括了所有必要的代码) 现在,问题是从Java 如何将更改通知正在运行的线程,java,multithreading,design-patterns,Java,Multithreading,Design Patterns,我正在处理一个客户机/服务器项目,它监视服务器中的系统事件,并向客户机发送更改通知。它由一个监视者对象和一个服务器对象组成,前者负责监视,后者为连接到它的每个客户端创建线程。考虑到下面的简化代码(我包括了所有必要的代码) 现在,问题是从mySrv对象接收到通知,并且mySrv的propertyChange被正确执行,并且disMsg被填充。但是,我不知道如何使用ClientHandler的run方法来执行notifyStatusChange()将更改发送给客户端。我试着连接线程和许多不同的东西,
mySrv
对象接收到通知,并且mySrv
的propertyChange
被正确执行,并且disMsg
被填充。但是,我不知道如何使用ClientHandler
的run
方法来执行notifyStatusChange()
将更改发送给客户端。我试着连接线程和许多不同的东西,但没有一个奏效。如果有人知道一个更好的方法,或者向我指出我的错误和最佳实践,或者具体告诉我如何实现这一点,我将不胜感激
谢谢
一种常见的模式是生产者消费者。线程可以共享一个
BlockingQueue
[1],其中生产者线程添加项目,消费者线程从集合中获取项目
有很多实现的例子
[1] 您的“propertyChange()”是否得到执行,如果是这样,您的代码应该可以正常工作。
无需再次执行“run()”或加入线程
如果您只想将更改通知正在运行的线程,那么下面的简单代码将起作用
package indika.java.core.network;
public class MyServer{
public boolean isChanged = false;
private String dispMsg;
public MyServer() throws InterruptedException {
Thread mthread = new Thread(new ClientThread());
mthread.start();
Thread.sleep(1000);
isChanged = true;
}
public class ClientThread implements Runnable {
public void run() {
boolean ok = true;
while (ok) {
System.out.println("Started thread!!!!");
if (isChanged) {
System.out.println("Server1: " + dispMsg);
notifyStatusChange();
isChanged = false;
ok = false;
}
}
}
}
public void notifyStatusChange() {
System.out.println("notifyStatusChange -- ");
}
public static void main(String[] args) throws InterruptedException {
new MyServer();
}}
我可以在这里看到一些不同的问题 服务器似乎在等待来自客户端的连接,并在收到连接时创建并启动
ClientHandler
线程。一旦接收到这样的连接,它的run
方法将在自己的线程中执行
因此,此时我们有两个线程,服务器线程和客户端线程,但是如果客户端在连接后没有向套接字写入任何内容,那么线程将在clientMessage=reader.readLine()处阻塞。
现在让我们假设在主线程中调用了propertyChange
,它将isChanged
设置为true
。如果我理解正确,您希望调用notifyStatusChange
。但也存在一些问题:
ischange
变为true时,ClientHandler.run
可能会被阻止从客户端连接读取
isChanged
为false。这是因为更改发生在不同的线程中。如果变量被声明为易失性
,则不会发生这种情况isChanged
设置为false
,因此即使该值传播到所有线程,也只有一个线程会打印通知我知道这不是完整的答案,但你需要解决这些问题 你看了吗?
ischange
定义在哪里?你让它变得不稳定了吗?(我不是说这是问题所在;我只是试图理解代码。)@ElliottFrisch,PropertyChangeListener
的使用已经实现了观察者/可观察设计模式,而且我接收观察者对象的通知也没有问题;但是,我无法将更改发送到ClientHandler
的run
方法。@ajb:isChange
在构造函数中定义,并且当从观察者
对象收到通知时,也会更改为true
。正如我前面提到的,我收到了通知,但是没有执行ClientHandler
的run
方法。我还修复了代码中的一些打字错误。在上面编辑的代码中,构造函数和主类的名称不匹配。很抱歉观察力很好。我根据您提到的步骤修复了问题,并且成功了!谢谢
package indika.java.core.network;
public class MyServer{
public boolean isChanged = false;
private String dispMsg;
public MyServer() throws InterruptedException {
Thread mthread = new Thread(new ClientThread());
mthread.start();
Thread.sleep(1000);
isChanged = true;
}
public class ClientThread implements Runnable {
public void run() {
boolean ok = true;
while (ok) {
System.out.println("Started thread!!!!");
if (isChanged) {
System.out.println("Server1: " + dispMsg);
notifyStatusChange();
isChanged = false;
ok = false;
}
}
}
}
public void notifyStatusChange() {
System.out.println("notifyStatusChange -- ");
}
public static void main(String[] args) throws InterruptedException {
new MyServer();
}}