英文:
Does ExecutorService consume thread capacity
问题
我正在尝试创建一个消息应用程序。我有一个名为 MessageServer
的类,我打算将客户端连接到这个类上。
每个 Client
类都实现了 Runnable
接口。
我的方法是在 MessageServer
类内部创建一个 ExecutorService
,然后从这里执行每个客户端。
我的问题是,我可以根据 Executors.newFixedThreadPool(x)
执行无限数量的 Runnable
吗,还是它们会被视为独立的线程?
如果可能的话,我也愿意采用新的方法。
我还从主方法中启动了 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();
// 读取客户端数据然后添加到列表
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);
}
}
}
}
超类 Server
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();
}
}
Client
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 与 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);
}
// 获取器-设置器-哈希码-相等
}
希望这能帮助你!
英文:
I am trying to create a messaging application. I have a class called MessageServer
and I intend to connect clients to this class.
Every Client
class implements Runnable
.
My approach is to create an ExecutorService
inside the MessageServer
class, and execute every client from here.
My question is, can I execute infinite amount Runnable
's depending on the Executors.newFixedThreadPool(x)
or do they count as individual threads?
I am open to new approaches if possible.
I also start the MessageServer thread from main method.
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);
}
}
}
}
Super class Server
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();
}
}
Client
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
答案1
得分: 2
> 我的问题是,我是否可以根据Executors.newFixedThreadPool(x)执行无限数量的Runnable,还是它们被视为单独的线程?
您可以添加比线程更多的可运行项。它们存储在队列中,并在有可用线程时执行。
在Executors.newFixedThreadPool
方法的Javadoc中:
> 创建一个线程池,它重用固定数量的线程,这些线程在共享的无限队列中运行。
所以,是的,它是“无限的”。
英文:
> My question is, can I execute infinite amount Runnable's depending on the Executors.newFixedThreadPool(x) or do they count as individual threads?
You can add far more runnables than threads. They are stored in a queue, and executed when a thread is available.
In the Javadoc of the Executors.newFixedThreadPool
method:
> Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue.
So, yes, it's "infinite".
答案2
得分: 2
> 我的问题是,我是否可以根据Executors.newFixedThreadPool(x)
执行无限数量的Runnable
,还是它们算作单独的线程?
具有固定大小的线程池在内部有一个队列,任务会被排队在那里。每个Runnable
都会被放入该队列中。如果一个线程完成了当前的任务,它会从队列中获取新的任务。
您可以排队的任务数量没有限制,除非受到硬件限制。例如,当您排队了20个任务,并且池中有10个线程时,只有其中的10个任务,或者更确切地说,只有10个Runnable
会被执行。在您的情况下,只有x
个客户端会在运行,因为池中只有x
个固定大小的线程。
在您的情况下,您应该使用Executors.newCachedThreadPool()
。这个线程池没有固定的大小限制,这使得池可以同时运行所有的客户端。
英文:
> My question is, can I execute infinite amount Runnable
s depending on the Executors.newFixedThreadPool(x)
or do they count as individual threads?
The thread pool with fixed size has internally a queue where tasks are queued. Each Runnable
is put into that queue. A thread takes a new task from the queue if it has finished its current task.
There is no limit of tasks you can queue, except hardware limits. When you queue e.g. 20 tasks and have 10 threads in the pool, only 10 of those tasks, or rather Runnable
s, are executed. In your case, only x
clients would be running because there are only x
threads in the pool with fixed size.
You should use Executors.newCachedThreadPool()
in your case. This thread pool doesn't have a limited size, which enables the pool to run all clients at the same time.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论