0

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 メソッド内でそのスレッドを開始します。

ただし、スレッド変数でフラグを呼び出すと、スレッドだけでなくプログラム全体が待機しています。どうすればこれを修正できますか?

4

1 に答える 1

4
  1. wait() notify() 呼び出されたのと同じオブジェクトを 別のスレッドが呼び出した場合にのみ、ロックを取り戻すことができますwait()

  2. 上記の声明に従って、私はあなたの問題を修正しようとします。

    • まず、クラス スコープで を作成して、他のスレッドがそれを見ることができるようにします。Object lock = new Object()

    • wait() and notify() は同期ブロックにある必要があるため、ロックを解除するオブジェクトを含む同期ブロックに入れます。 notify

      例:

      synchronized(lock) {
         lock.notify();
      }
      
于 2012-07-22T15:29:08.970 に答える