java - 如何让单个线程而不是整个程序等待?

标签 java multithreading wait notify

我正在编写一个服务器程序,当 ArrayList 中有客户端时,它会通过 RMI 通知客户端。

但是我无法停止并恢复通知客户端的线程。

这是我的代码:

package eu.craenhals;

import java.awt.Dimension;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JFrame;
import javax.swing.JTextArea;

import java.awt.BorderLayout;

public class Server extends JFrame {
    private static final long serialVersionUID = 1L;
    private JTextArea textArea;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss");
    private ServerImpl server;
    private ServerThread thread;

    public Server() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Server");
    setSize(new Dimension(521, 333));

    textArea = new JTextArea();
    textArea.setEditable(false);
    getContentPane().add(textArea, BorderLayout.CENTER);

    initialize();
    log("Server opgestart op poort 9878");
    }

    private void initialize() {
    log("Server wordt opgestart");
    try {
        Registry registry = LocateRegistry.createRegistry(9878);
        server = new ServerImpl();
        registry.rebind("server", server);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
    Object lock = new Object();
    thread = new ServerThread(lock);
    thread.start();
    synchronized(lock) {
        try {
        lock.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
    }
    }

    public static void main(String[] args) {
    Server server = new Server();
    server.setVisible(true);
    }

    private void log(String message) {
    textArea.append(dateFormat.format(new Date()) + " - " + message + "\n");
    }

    class ServerImpl extends UnicastRemoteObject implements ServerInterface {
    private static final long serialVersionUID = 1L;
    private ArrayList<ClientInterface> clients = new ArrayList<ClientInterface>();

    protected ServerImpl() throws RemoteException {
        super();
    }

    private void notifyClients() {
        log("Clients verwittigen");
        for (ClientInterface client : clients) {
        try {
            client.notify("Interface van client " + client.getName() + " updaten");
        } catch (RemoteException e) {
            log(e.getMessage());
        }
        }
    }

    @Override
    public void addClient(ClientInterface client) throws RemoteException {
        if (clients.contains(client)) {
        log("Client '" + client.getName() + "' niet toegevoegd, want bestaat al");
        throw new RemoteException("Client niet toegevoegd, want bestaat al");
        }
        clients.add(client);
        log("Client '" + client.getName() + "' toegevoegd");
    }

    @Override
    public void removeClient(ClientInterface client) throws RemoteException {
        boolean isVerwijderd = clients.remove(client);
        if (isVerwijderd) {
        log("Client '" + client.getName() + "' verwijderd");
        } else {
        log("Client '" + client.getName() + "' niet verwijderd, want bestond niet");
        throw new RemoteException("Client niet verwijderd, want bestond niet");
        }

    }
    }

    class ServerThread extends Thread {
    private final Object lock;

    public ServerThread(Object lock) {
        this.lock = lock;
    }

    public void flag() {
        synchronized (lock) {
        System.out.println("Before Wait");
        try {
            lock.wait();
            System.out.println("After Being Notified");
        } catch (InterruptedException ex) {
            System.out.println("Thread interrupted");
        }
        }
    }

    public void unflag() {
        synchronized (lock) {
        System.out.println("Before Notify All");
        lock.notifyAll();
        System.out.println("After Notify All Method Call");
        }
    }

    public void run() {
        while (true) {
        System.out.println("In serverthread");
        server.notifyClients();
        synchronized (lock) {
            try {
            lock.wait(5000);
            } catch (InterruptedException ex) {
            }
        }
        }
    }
    }
}

我有一个 ServerThread 变量,我在初始化方法中启动该线程。

但是,当我在线程变量上调用 flag 时,我的整个程序都在等待,而不仅仅是线程。我该如何解决这个问题?

最佳答案

  1. wait() 仅当另一个线程调用时才能重新获得锁定 notify() 在同一对象上 wait() 被召唤。

  2. 现在根据上述说法,我会尽力纠正您的问题。

    • 首先创建 Object lock = new Object()类范围内,因此其他线程可以看到它。

    • wait() and notify() 必须位于同步块(synchronized block)中,因此请输入您的 notify 与要释放锁的对象一起进入同步块(synchronized block)。

      示例:

      synchronized(lock) {
         lock.notify();
      }
      

关于java - 如何让单个线程而不是整个程序等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11601501/

相关文章:

java - XML 布局到 Java 代码转换器

java - Renjin支持哪些R版本?

java - 我试图在java中将19位数字除以100(19位数字/100)

C++ lambda表达式线程循环

c++ - boost::unique_lock,多次读取正在减慢编写器的速度

c# - 不眠等待?

java - 在 2 个数组列表中搜索对象

c# - 使用 async 和 DataRow 的非线程安全代码

java - Java中 "wait()"与 "sleep()"之间的区别

PHP RabbitMQ setTimeout 或其他停止等待队列的选项