我正在用java創建一個客戶端 - 服務器應用程序,該應用程序允許使用客戶端擺動應用程序(記事本)連接到服務器的許多人。一旦連接,每個客戶端將不得不請求記事本的控制權,以便他們可以編輯它,然後放棄控制權,並將結果發送到所有其他客戶端的平板電腦上。Java多線程服務器邏輯,同步關鍵字,問題
我遇到的主要問題是多線程服務器邏輯,使用主服務器實例和多個線程,與客戶端每一個處理的通信。
我不確定我選擇的結構是否會工作,或者是否會有參與我缺乏的主題是如何工作的理解有些問題,導致數據損壞或者其他某個線程相關的問題。
無論如何,這是服務器端的代碼,我想知道是否有人能告訴我,如果這個系統將沒有錯誤的工作?當然還有更多的邏輯要添加,比如連接數量上限,鎖的等待列表等,但我主要關注線程之間的通信。
我也想知道如何從線程內訪問服務器實例方法,因爲我不知道。 -note,這已經算出來了,我使用了一個共享的「lock」對象,它有一個線程實例列表,每個線程實例都有鎖定實例,所以他們可以在eachother上調用方法。
非常感謝。
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.
}
}
嗨,感謝您的迴應,我確定這些實現更適合,但我忘了提及這是一個大學項目,必須涉及擺動和套接字不幸:( –
你會想添加「作業「標籤到您的帖子然後... –
噢好吧,我是新來的,有史以來第一個問題:p –