ExecutorService是否消耗线程容量

问题描述 投票:0回答:2

我正在尝试创建消息传递应用程序。我有一个名为MessageServer的课程,我打算将客户端连接到该课程。每个Client类都实现Runnable。我的方法是在ExecutorService类中创建一个MessageServer,然后从此处执行每个客户端。

我的问题是,我可以根据Runnable执行无限量的Executors.newFixedThreadPool(x)还是将其视为单个线程?

如果可能,我愿意接受新方法。我也从主要方法启动MessageServer线程。

MessageServer

public class MessageServer extends Server implements Runnable{

    static LinkedList<Message> messages = new LinkedList<>();

    LinkedList<Client> clients = new LinkedList<>();

    ExecutorService clientPool = Executors.newFixedThreadPool(3);

    public MessageServer() throws IOException {
        super(Vars.MESSAGE_PORT);
    }

    public void addToMessages(Message message) {
        if (!messages.contains(message)) {
            messages.add(message);
        }
    }

    @Override
    public void run() {
        while(true){
            try {
                Socket client = serverSocket.accept();

                //Read Client data then add to the list
                ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
                ObjectInputStream in =  new ObjectInputStream(client.getInputStream());

                Client current = (Client)in.readObject();
                clients.add(current);
            } catch (Exception ex) {
                Logger.getLogger(MessageServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

}

超类 服务器

public class Server{
    InetAddress address;

    LinkedList<Client> clients = new LinkedList<>();

    protected ServerSocket serverSocket;

    public Server(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(Vars.SERVER_TIMEOUT_MS);

        //ip = Utilities.getIp();

        address = serverSocket.getInetAddress();
    }
}

客户

public class Client implements Serializable {

protected String nickname;
protected long id;
protected int key;

// MessageServer
protected transient ObjectOutputStream msgOut;
protected transient ObjectInputStream msgIn;
protected transient Socket messageSocket;

protected transient Socket videoSocket;


public Client(String nickname){
    this.nickname = nickname;
    createid();
    makeConnection();
    key = (int) (Math.random() * 8999) + 1000;
}

void makeConnection(){
    try {
        messageSocket = new Socket(Vars.IP, Vars.MESSAGE_PORT);
        //TODO make connection with videoServer
        msgOut = new ObjectOutputStream(messageSocket.getOutputStream());
        msgIn = new ObjectInputStream(messageSocket.getInputStream());

        msgOut.writeObject(this);

    } catch (IOException ex) {
        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
    }
}

final void createid(){
    id = 3;
    id = 13 * id + Objects.hashCode(this.nickname);
}

// Getters-setters-hashcode-equals
java multithreading sockets oop executorservice
2个回答
2
投票

我的问题是,我可以根据Executors.newFixedThreadPool(x)执行无限量的Runnable还是将其视为单个线程?

您可以添加的可运行对象比线程多得多。它们存储在队列中,并在线程可用时执行。

Executors.newFixedThreadPool method的Javadoc中:

创建一个线程池,该线程池可重用在共享的无边界队列上操作的固定数量的线程。

所以,是的,它是“无限”。


1
投票

我的问题是,我可以根据Executors.newFixedThreadPool执行无限数量的Runnable还是将其视为单个线程?

具有固定大小的线程池在内部具有一个队列,其中将任务排队。每个Executors.newFixedThreadPool(x)都放入该队列。如果线程已完成当前任务,则它将从队列中获取新任务。

除硬件限制外,没有其他可以排队的任务限制。当您排队时20个任务以及池中有10个线程,这些任务中只有10个,或者说是Runnable被执行。在您的情况下,仅Runnable个客户端会运行,因为池中只有x个线程具有固定大小。

您应使用x。此线程池没有大小限制,这使线程池可以同时运行所有客户端。

© www.soinside.com 2019 - 2024. All rights reserved.