Java 如何让一个线程而不是整个程序等待?
我正在编写一个服务器程序,当ArrayList中有客户机时,通过RMI通知客户机 但是,我不能停止并恢复通知客户端的线程 这是我的密码:Java 如何让一个线程而不是整个程序等待?,java,multithreading,wait,notify,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
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) {
}
}
}
}
}
}
package eu.craenhals;
导入java.awt.Dimension;
导入java.rmi.RemoteException;
导入java.rmi.registry.LocateRegistry;
导入java.rmi.registry.registry;
导入java.rmi.server.UnicastRemoteObject;
导入java.text.simpleDataFormat;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入javax.swing.JFrame;
导入javax.swing.JTextArea;
导入java.awt.BorderLayout;
公共类服务器扩展了JFrame{
私有静态最终长serialVersionUID=1L;
私人JTEXTEXTAREA textArea;
私有SimpleDataFormat dateFormat=新SimpleDataFormat(“dd/MM/yyyy-HH:MM:ss”);
私有服务器impl服务器;
私有服务器线程;
公共服务器(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(“服务器”);
设置尺寸(新尺寸(521333));
textArea=新的JTextArea();
textArea.setEditable(false);
getContentPane().add(textArea,BorderLayout.CENTER);
初始化();
日志(“服务器opgestart op poort 9878”);
}
私有void初始化(){
日志(“服务器wordt optart”);
试一试{
Registry=LocateRegistry.createRegistry(9878);
server=newserverimpl();
registry.rebind(“server”,server);
}捕获(远程异常){
e、 printStackTrace();
}
对象锁=新对象();
线程=新服务器线程(锁);
thread.start();
已同步(锁定){
试一试{
lock.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
公共静态void main(字符串[]args){
服务器=新服务器();
setVisible(true);
}
私有无效日志(字符串消息){
textArea.append(dateFormat.format(new Date())+“-”+message+“\n”);
}
类ServerImpl扩展UnicastRemoteObject实现ServerInterface{
私有静态最终长serialVersionUID=1L;
私有ArrayList客户端=新ArrayList();
受保护的ServerImpl()引发RemoteException{
超级();
}
私有客户机(){
日志(“客户verwittigen”);
for(客户端界面客户端:客户端){
试一试{
client.notify(“Interface van client”+client.getName()+“updaten”);
}捕获(远程异常){
日志(如getMessage());
}
}
}
@凌驾
public void addClient(ClientInterface客户端)引发RemoteException{
if(clients.contains(client)){
日志(“Client'”+Client.getName()+“'niet toegevogd,want bestaat al”);
抛出新的RemoteException(“客户端niet-toegevoegd,want-bestaat al”);
}
客户。添加(客户);
日志(“Client'+Client.getName()+“'toegevoegd”);
}
@凌驾
public void removeClient(ClientInterface客户端)引发RemoteException{
布尔值isVerwijderd=clients.remove(client);
如果(isVerwijderd){
日志(“Client'+Client.getName()+“'verwijderd”);
}否则{
日志(“Client'”+Client.getName()+“'niet verwijderd,want bestond niet”);
抛出新的RemoteException(“客户机niet verwijderd,want bestond niet”);
}
}
}
类ServerThread扩展线程{
私有最终对象锁;
公共服务器线程(对象锁){
this.lock=锁;
}
公共无效标志(){
已同步(锁定){
System.out.println(“等待前”);
试一试{
lock.wait();
System.out.println(“收到通知后”);
}捕获(中断异常例外){
System.out.println(“线程中断”);
}
}
}
公共空间{
已同步(锁定){
System.out.println(“通知所有人之前”);
lock.notifyAll();
System.out.println(“通知所有方法调用之后”);
}
}
公开募捐{
while(true){
System.out.println(“In-serverthread”);
notifyClients();
已同步(锁定){
试一试{
锁。等待(5000);
}捕获(中断异常例外){
}
}
}
}
}
}
我有一个ServerThread变量,并在initialize方法中启动该线程
然而,当我在线程变量上调用flag时,我的整个程序都在等待,而不仅仅是线程。我怎样才能解决这个问题
wait()
只有当另一个线程在调用该对象的同一个对象上调用
时,才能重新获得锁定。
- 首先,在类作用域中创建
,以便其他线程可以看到它。对象锁=新对象()
必须在同步块中,因此将您的wait()和notify()
与要释放其锁的对象一起放入同步块中。 示例:synchronized(lock) { lock.notify(); }
wait()
只有当另一个线程在调用该对象的同一个对象上调用
时,才能重新获得锁定。
- 首先,在类作用域中创建
,以便其他线程可以看到它。对象锁=新对象()
wait()和notify()