gpt4 book ai didi

Java 多线程服务器逻辑,Synchronized 关键字,问题

转载 作者:搜寻专家 更新时间:2023-11-01 03:28:05 27 4
gpt4 key购买 nike

我正在用 java 创建一个客户端-服务器应用程序,它将允许许多人使用客户端 swing 应用程序(记事本)连接到服务器。连接后,每个客户端都必须请求对记事本的控制,以便他们可以对其进行编辑,然后放弃控制,发送他们的结果以显示在所有其他客户端的笔记本上。

我遇到的主要问题是多线程服务器逻辑,使用主服务器实例和多个线程,每个线程处理与客户端的通信。

我不确定我选择的结构是否可行,或者是否会因为我对线程工作原理缺乏了解而导致数据损坏或其他一些与线程相关的问题。

无论如何,这是服务器代码,我想知道是否有人可以告诉我这个系统是否可以正常工作?当然还有更多的逻辑要添加,比如连接数的上限、锁的等待列表等。但我主要关心线程之间的通信。

我也想知道如何从线程内部访问服务器实例方法,因为我不确定。 - 注意,这已经弄清楚了,我正在使用共享的“锁”对象,它有一个线程实例列表,每个线程实例都有锁实例,所以它们可以互相调用方法。

非常感谢。

import java.net.*;
import java.io.*;
import java.util.ArrayList;


public class server {

private ArrayList<ClientServiceThread> SocketList;
private int lock = 0;
private ServerSocket myServerSocket;
private Socket mySocket;

public static void main(String[] args)
{
server myserver = new server();
}

public server()
{

/**
* This will (when finished) accept only a certain number of connections,
* and will then finish the constructor by breaking the while loop. It will
* then sit here waiting for the synchronised methods to be called by its worker
* threads.
*/
try{

myServerSocket = new ServerSocket(8080);

}catch(Exception e)
{
System.out.println("Could not create serversocket "+e);
}

int id = 1;
while(true)
{
try{

mySocket = myServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(mySocket, id);
SocketList.add(cliThread);
id++;
cliThread.start();

}catch(Exception e)
{
System.out.println("Problem with accepting connections");
}

}

}//end constructor


public synchronized boolean acquireLock(int id)
{
/**
* Here any spawned thread can try to acquire the lock,
* so it can be the one to send the data (synchronised to prevent data corruption)
*/

if(this.lock == 0){
this.lock = id;
return true;
}
else
{
return false;
}

}

public synchronized void releaseLock(int id)
{
/**
* Any thread can call this, releasing the lock. of course, the lock will only be
* released if the thread calling it actually owns the lock.
*/

if(id == this.lock)
{
this.lock = 0;
}
else
{
//do nothing
}
}

public synchronized void publish(String toSend)
{
/**
* When a thread in control of the lock wants to publish to all other threads, it
* invokes this method, which then calls another synchronised method on each thread
* in the list, telling it to write to it's client with the new data.
*/

for(int i = 0; i<this.SocketList.size(); i++)
{
if(i != this.lock)
{
this.SocketList.get(i).sendData(toSend);
}
}
}


}



class ClientServiceThread extends Thread{

Socket mySocket;
int id;
boolean hasControl = false;

public ClientServiceThread(Socket mySocket, int id)
{
/**
* this constructor gives it the ID and the socket for communication, it will
* then be run
*/
this.mySocket = mySocket;
this.id = id;

}

@Override
public void run()
{
//listen, it will be either a request, or some data
//based on whether the client is the one in control or not (hasControl)
try{
//create buffered reader

if(!this.hasControl)
{
//it has control, so wait for the lines
}
else
{
//read in one line and then call acquire lock because we know
//that it has sent a request for control
// how do i access the original class for acquireLock();?


}


}catch(IOException e)
{
System.out.println("Problem reading from the socket");
}

}

public synchronized void sendData(String toSend)
{
//create writer and send to my client, saying "true" or some other message
//the client will recognise as the go-ahead to edit the data.
}


}

最佳答案

你可能最好使用像 MINA 这样的东西而不是自己滚动。将客户端命令放入并发队列并一次处理一个,这样您就不必担心同步问题。

或者,考虑使用 RESTful 接口(interface)而不是套接字(或者就此而言,使用 applet 以外的东西,例如 Ext JS)。

关于Java 多线程服务器逻辑,Synchronized 关键字,问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8022998/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com