如何通知正在运行的线程更改

时间:2013-12-30 20:15:04

标签: java multithreading design-patterns

我正在开发一个客户端/服务器项目,该项目在服务器中监视系统事件并向客户端发送通知更改。它由一个观察的Watcher对象和为每个连接它的客户创建线程的服务器对象组成。考虑下面的简化代码(我包括了所有必要的代码)

现在,问题是从mySrv对象收到通知,propertyChange的{​​{1}}已正确执行,并且mySrv已填充。但是,我不知道如何使用disMsg run方法来执行ClientHandler以将更改发送给客户端。我尝试加入线程和许多不同的东西但没有工作。如果有人知道更好的方法或者指出我的错误和最佳实践,我会非常感激,或者向我展示如何实现这一目标。

谢谢,

notifyStatusChange()

3 个答案:

答案 0 :(得分:2)

我可以在这里看到一些不同的问题。

服务器似乎等待来自客户端的连接,并在收到连接时创建并启动ClientHandler线程。一旦收到这样的连接,它的run方法将在其自己的线程中执行。

所以此时我们有两个线程,即服务器线程和客户端线程,但是如果客户端在连接后没有向套接字写入任何东西,则线程将在clientMessage = reader.readLine())

处阻塞

现在让我们假设在主线程中调用propertyChange,并将isChanged设置为true。如果我理解正确,你期待被叫notifyStatusChange。但是有一些问题:

    ClientHandler.run变为isChanged

    时,
  1. true可能会被阻止从客户端连接读取

  2. 即使从套接字读取了某些内容,该线程也可能会发现isChanged为false。这是因为更改发生在不同的线程中。如果变量声明为volatile,则不会发生这种情况。

  3. 服务器接受多个连接,每个连接使用不同的线程。但是每个线程的run方法可以将isChanged设置为false,因此即使该值传播到所有线程,也只有其中一个会打印通知。

  4. 我知道这不是完整的答案,但你需要解决这些问题。

答案 1 :(得分:1)

常见的模式是producer-consumer。线程可以共享BlockingQueue [1],其中生产者线程添加项目,而消费者线程从集合中获取它。

有很多实现的例子。

[1] http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

答案 2 :(得分:0)

你的“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();
}}