[英]How can I make this code wait until a Thread is available in the Thread Pool?
我想在網絡編程和Java線程池方面進行一些練習。 這是我編寫的示例代碼:
/* User: koray@tugay.biz Date: 21/02/15 Time: 13:30 */
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MyServer {
static List<ServerSocketThread> myThreadPool = new ArrayList<ServerSocketThread>();
static int numberOfCurrentConnections = 0;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
ServerSocketThread threadOne = new ServerSocketThread(null);
ServerSocketThread threadTwo = new ServerSocketThread(null);
myThreadPool.add(threadOne);
myThreadPool.add(threadTwo);
while (true) {
if(numberOfCurrentConnections < 2) {
Socket accept = serverSocket.accept();
ServerSocketThread thread = myThreadPool.get(numberOfCurrentConnections);
thread.setSocket(accept);
thread.start();
numberOfCurrentConnections++;
} else {
// I want to force the client to wait until a new Thread is available from the pool.
}
}
}
public static void informFinished() {
numberOfCurrentConnections--;
}
}
ServerSocketThread類如下:
/* User: koray@tugay.biz Date: 21/02/15 Time: 18:14 */
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class ServerSocketThread extends Thread {
Socket socket;
public ServerSocketThread(Socket accept) {
this.socket = accept;
}
@Override
public void run() {
try {
Scanner scanner = new Scanner(socket.getInputStream());
String readLine;
while (!(readLine = scanner.nextLine()).equals("bye")) {
System.out.println(readLine);
}
new PrintWriter(socket.getOutputStream()).write("Bye then..");
socket.close();
MyServer.informFinished();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
好吧,我可以使用2個不同的終端連接到我的服務器,就像這樣:
Korays-MacBook-Pro:~ koraytugay$ telnet localhost 8888
Trying ::1...
Connected to localhost.
Escape character is '^]'.
laylay
bombom
並且第3個連接(如果建立)將不起作用,因為線程池中只有2個線程。 但是我找不到讓第三位客戶等到客戶說“再見”的方法。 我想做的是,在兩個第一個連接的客戶端之一斷開連接之后,將一個線程分配給正在等待的第三個客戶端,但是如何?
我將回答我自己的問題,使它像這樣工作:
/* User: koray@tugay.biz Date: 21/02/15 Time: 21:12 */
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Stack;
public class MyConnectionAccepter {
private Stack<MySocketThread> mySocketThreads = new Stack<MySocketThread>();
private volatile int currentNumberOfConnections = 0;
public MyConnectionAccepter() {
MySocketThread mySocketThreadOne = new MySocketThread(this);
MySocketThread mySocketThreadTwo = new MySocketThread(this);
mySocketThreadOne.setDaemon(true);
mySocketThreadTwo.setDaemon(true);
mySocketThreadOne.start();
mySocketThreadTwo.start();
mySocketThreads.push(mySocketThreadOne);
mySocketThreads.push(mySocketThreadTwo);
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
while (currentNumberOfConnections < 2) {
System.out.println("Blocking now:");
Socket accept = serverSocket.accept();
System.out.println("Connection accepted..");
MySocketThread mySocketThread = mySocketThreads.pop();
mySocketThread.setSocket(accept);
System.out.println("Incrementing connections..");
currentNumberOfConnections++;
System.out.println("End of while..");
}
}
}
public void informIAmDone(MySocketThread mySocketThread) {
mySocketThreads.push(mySocketThread);
currentNumberOfConnections--;
}
}
和
/* User: koray@tugay.biz Date: 21/02/15 Time: 21:04 */
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class MySocketThread extends Thread {
private volatile Socket socket;
MyConnectionAccepter myConnectionAccepter;
public MySocketThread(MyConnectionAccepter myConnectionAccepter) {
this.myConnectionAccepter = myConnectionAccepter;
}
@Override
public synchronized void run() {
System.out.println("Started...");
serve();
}
public void setSocket(Socket socket) {
this.socket = socket;
System.out.println("Socket not null anymore..");
}
public void serve() {
while(socket == null) {
}
while (socket != null) {
Scanner scanner = null;
try {
scanner = new Scanner(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
String readLine;
while (!(readLine = scanner.nextLine()).equals("bye")) {
System.out.println(readLine);
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
myConnectionAccepter.informIAmDone(this);
}
serve();
}
}
和測試類別:
/* User: koray@tugay.biz Date: 21/02/15 Time: 21:18 */
import java.io.IOException;
public class MyTestClass {
public static void main(String[] args) throws IOException {
MyConnectionAccepter myConnectionAccepter = new MyConnectionAccepter();
myConnectionAccepter.start();
}
}
我建議您按照本文所述創建線程池: http : //tutorials.jenkov.com/java-concurrency/thread-pools.html
因此,基本上,除了線程池之外,您還維護一個任務隊列。 池中的每個線程都在不斷輪詢任務隊列中的任務。 只要有任務可用(隊列不為空),線程就會將其拾取並執行。 在您的情況下,任務將是處理客戶端連接。 池中的線程數是有限的(在這種情況下為2)。 因此,任何時候可以同時處理的連接數是2。只有當兩個線程之一完成執行當前任務時,它才會選擇下一個。 每次收到新的連接請求時,便將新任務添加到隊列中。
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.