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

时间:2012-07-22 15:22:14

标签: 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变量,我在initialize方法中启动该线程。

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

1 个答案:

答案 0 :(得分:4)

  1. wait() 只有当另一个线程在 {{1}的同一对象上调用 notify() 时才能重新获得锁定}} 被调用。

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

    • 首先创建 类范围内的wait(),以便其他线程可以看到它。

    • Object lock = new Object() 必须在同步块中,因此将您的 wait() and notify() 放入同步块中,其对象的锁定将被释放。

      示例:

      notify