简体   繁体   English

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

[英]Java Multi-Threaded Server logic, Synchronized keyword, issue

I am creating a client-server application in java which will allow a number of people, using a client side swing application, (a notepad) to connect to a server. 我正在用Java创建一个客户端服务器应用程序,它将允许许多人使用客户端摆动应用程序(记事本)连接到服务器。 Once connected, each client will have to request control of the notepad so they can edit it, and then relinquish control, sending their result to be displayed on the pad of all other clients. 连接后,每个客户端都必须请求控制记事本,以便他们可以对其进行编辑,然后放弃控制,将其结果发送到所有其他客户端的记事本上。

The main problem i am having is the multi-threaded server logic, using the main server instance and several threads, each one handling communication with a client. 我遇到的主要问题是使用主服务器实例和多个线程的多线程服务器逻辑,每个线程处理与客户端的通信。

I am unsure whether the structure i have chosen will work or whether there will be some issue involved with my lack of understanding of how threads work, causing data corruption or some other thread related issue. 我不确定我选择的结构是否有效,或者由于我对线程如何工作缺乏理解而导致某些问题,从而导致数据损坏或其他与线程相关的问题。

anyway, this is the server code, i was wondering if anyone could tell me if this system will work without error? 无论如何,这是服务器代码,我想知道是否有人可以告诉我该系统是否可以正常运行? There is of course more logic to add, like a cap on number of connections, a waiting list for the lock, etc. but i am mainly concerned with communication between threads. 当然,还有更多的逻辑可以添加,例如连接数上限,锁的等待列表等,但是我主要关心线程之间的通信。

I am also wondering how to access the server instance methods from inside the thread, as i am not sure. 我也想知道如何从线程内部访问服务器实例方法,因为我不确定。 -note, this has been figured out, i am using a shared "lock" object, which has a list of the thread instances, and each thread instance has the lock instance, so they can call methods on eachother. -注意,这已经弄清楚了,我正在使用一个共享的“锁”对象,该对象具有线程实例的列表,并且每个线程实例都具有该锁实例,因此它们可以彼此调用方法。

thanks very much. 非常感谢。

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. 
    }


}

You're probably better off using something like MINA instead of rolling your own. 您最好使用MINA之类的东西,而不要自己动手。 Drop client commands into a concurrent queue and process them one at a time so you don't have to worry about synchronization. 将客户端命令放入并发队列中,并一次处理一个,因此您不必担心同步。

Alternatively, consider using a RESTful interface instead of sockets (or for that matter, something other than an applet, like Ext JS). 或者,考虑使用RESTful接口而不是套接字(或者就此而言,使用Applet之外的其他东西,例如Ext JS)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM