Java计划执行器线程进入等待状态
因此,我尝试从Java客户机到Go服务器实现一个基本的异步消息传递协议,使用两个自定义线程和一个调度线程执行器。所以,我从Java客户机到Go服务器启动一个TCP套接字,并在两侧设置读写缓冲区 Writer线程将对应于每个请求的唯一ID保存到Redis服务器中,并使用TCP套接字上的PrintWriter写入请求 WriterThreadJava计划执行器线程进入等待状态,java,multithreading,sockets,asynchronous,jedis,Java,Multithreading,Sockets,Asynchronous,Jedis,因此,我尝试从Java客户机到Go服务器实现一个基本的异步消息传递协议,使用两个自定义线程和一个调度线程执行器。所以,我从Java客户机到Go服务器启动一个TCP套接字,并在两侧设置读写缓冲区 Writer线程将对应于每个请求的唯一ID保存到Redis服务器中,并使用TCP套接字上的PrintWriter写入请求 WriterThread public class WithdrawRequestWriter extends Thread { private static final i
public class WithdrawRequestWriter extends Thread {
private static final int START_ACCOUNT_NO = 1;
private static final int END_ACCOUNT_NO = 2_000;
private static final int AMOUNT_TO_WITHDRAW = 100;
private PrintWriter writer;
private Jedis jedis;
public WithdrawRequestWriter(PrintWriter writer, Jedis jedis) {
this.writer = writer;
this.jedis = jedis;
}
@Override
public void run() {
int i = 0;
for (int accountNo = START_ACCOUNT_NO; accountNo <= END_ACCOUNT_NO; accountNo++) {
String uniqueId = UUID.randomUUID().toString();
if (jedis.set(uniqueId, String.valueOf(accountNo), "NX", "EX", 10) != null) {
writer.write(uniqueId + " " + accountNo + " " + AMOUNT_TO_WITHDRAW + "\n");
writer.flush();
} else {
System.err.println("Setting of UUID in redis failed: " + uniqueId);
}
}
}
}
public class WithdrawRequestReader extends Thread {
private BufferedReader reader;
private Jedis jedis;
public WithdrawRequestReader(BufferedReader reader, Jedis jedis) {
this.reader = reader;
this.jedis = jedis;
}
@Override
public void run() {
String response;
while (true) {
try {
if ((response = reader.readLine()) != null) {
String[] tokenizedResponse = response.split(" ");
System.out.println("Response is: " + response);
String value = jedis.get(tokenizedResponse[0]);
if (value != null) {
System.out.println("Request Token: " + tokenizedResponse[0]
+ " | Status: " + tokenizedResponse[1]
+ " | Account: " + tokenizedResponse[2]
+ " | Amount: " + tokenizedResponse[3]
+ " | Remaining Balance: " + tokenizedResponse[4]
+ " | ResponeStr: " + tokenizedResponse[5]);
}
} else {
System.out.println("Waiting for response...");
}
} catch (IOException ex) {
ex.printStackTrace();
System.exit(3);
}
}
}
}
public class TestClient {
private static final String HOSTNAME = "localhost";
private static final int PORT = 12410;
public static void main(String[] args) throws IOException {
Socket socket = new Socket(HOSTNAME, PORT);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Jedis jedis = new Jedis("localhost");
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
// ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
WithdrawRequestReader readerThread = new WithdrawRequestReader(reader, jedis);
WithdrawRequestWriter writerThread = new WithdrawRequestWriter(writer, jedis);
scheduledExecutorService.schedule(writerThread, 0, TimeUnit.MILLISECONDS);
scheduledExecutorService.schedule(readerThread, 0, TimeUnit.MILLISECONDS);
}
}
主线程
public class WithdrawRequestWriter extends Thread {
private static final int START_ACCOUNT_NO = 1;
private static final int END_ACCOUNT_NO = 2_000;
private static final int AMOUNT_TO_WITHDRAW = 100;
private PrintWriter writer;
private Jedis jedis;
public WithdrawRequestWriter(PrintWriter writer, Jedis jedis) {
this.writer = writer;
this.jedis = jedis;
}
@Override
public void run() {
int i = 0;
for (int accountNo = START_ACCOUNT_NO; accountNo <= END_ACCOUNT_NO; accountNo++) {
String uniqueId = UUID.randomUUID().toString();
if (jedis.set(uniqueId, String.valueOf(accountNo), "NX", "EX", 10) != null) {
writer.write(uniqueId + " " + accountNo + " " + AMOUNT_TO_WITHDRAW + "\n");
writer.flush();
} else {
System.err.println("Setting of UUID in redis failed: " + uniqueId);
}
}
}
}
public class WithdrawRequestReader extends Thread {
private BufferedReader reader;
private Jedis jedis;
public WithdrawRequestReader(BufferedReader reader, Jedis jedis) {
this.reader = reader;
this.jedis = jedis;
}
@Override
public void run() {
String response;
while (true) {
try {
if ((response = reader.readLine()) != null) {
String[] tokenizedResponse = response.split(" ");
System.out.println("Response is: " + response);
String value = jedis.get(tokenizedResponse[0]);
if (value != null) {
System.out.println("Request Token: " + tokenizedResponse[0]
+ " | Status: " + tokenizedResponse[1]
+ " | Account: " + tokenizedResponse[2]
+ " | Amount: " + tokenizedResponse[3]
+ " | Remaining Balance: " + tokenizedResponse[4]
+ " | ResponeStr: " + tokenizedResponse[5]);
}
} else {
System.out.println("Waiting for response...");
}
} catch (IOException ex) {
ex.printStackTrace();
System.exit(3);
}
}
}
}
public class TestClient {
private static final String HOSTNAME = "localhost";
private static final int PORT = 12410;
public static void main(String[] args) throws IOException {
Socket socket = new Socket(HOSTNAME, PORT);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Jedis jedis = new Jedis("localhost");
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
// ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
WithdrawRequestReader readerThread = new WithdrawRequestReader(reader, jedis);
WithdrawRequestWriter writerThread = new WithdrawRequestWriter(writer, jedis);
scheduledExecutorService.schedule(writerThread, 0, TimeUnit.MILLISECONDS);
scheduledExecutorService.schedule(readerThread, 0, TimeUnit.MILLISECONDS);
}
}
当我使用singlePoolThreadExecutor时,任务按顺序执行(如预期的那样),一切都会顺利进行。但是,当我将threadPoolExecutor与两个线程一起使用时,在很少的读写操作之后,它们会无限期地进入等待状态。如果出现死锁,我会从在线可用的免费工具中进行检查,但没有得到任何帮助。下面是线程被卡住时的转储
线程转储
Full thread dump Java HotSpot(TM) 64-Bit Server VM (9.0.4+11 mixed mode):
"DestroyJavaVM" #16 prio=5 os_prio=31 tid=0x00007f974e06d000 nid=0x2503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"pool-1-thread-2" #15 prio=5 os_prio=31 tid=0x00007f974e06c000 nid=0x6003 waiting on condition [0x000070000c819000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@9.0.4/Native Method)
- parking to wait for <0x0000000747cf64b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@9.0.4/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@9.0.4/AbstractQueuedSynchronizer.java:2062)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@9.0.4/ScheduledThreadPoolExecutor.java:1119)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@9.0.4/ScheduledThreadPoolExecutor.java:848)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@9.0.4/ThreadPoolExecutor.java:1092)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@9.0.4/ThreadPoolExecutor.java:1152)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@9.0.4/ThreadPoolExecutor.java:641)
at java.lang.Thread.run(java.base@9.0.4/Thread.java:844)
"pool-1-thread-1" #14 prio=5 os_prio=31 tid=0x00007f974e8a9800 nid=0x5e03 waiting on condition [0x000070000c716000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@9.0.4/Native Method)
- parking to wait for <0x0000000747cf64b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@9.0.4/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@9.0.4/AbstractQueuedSynchronizer.java:2062)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@9.0.4/ScheduledThreadPoolExecutor.java:1119)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java.base@9.0.4/ScheduledThreadPoolExecutor.java:848)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@9.0.4/ThreadPoolExecutor.java:1092)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@9.0.4/ThreadPoolExecutor.java:1152)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@9.0.4/ThreadPoolExecutor.java:641)
at java.lang.Thread.run(java.base@9.0.4/Thread.java:844)
"Service Thread" #11 daemon prio=9 os_prio=31 tid=0x00007f974d827000 nid=0xa003 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=31 tid=0x00007f974e078800 nid=0x5903 runnable [0x000070000c40d000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(java.base@9.0.4/Native Method)
at java.net.SocketInputStream.socketRead(java.base@9.0.4/SocketInputStream.java:116)
at java.net.SocketInputStream.read(java.base@9.0.4/SocketInputStream.java:171)
at java.net.SocketInputStream.read(java.base@9.0.4/SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(java.base@9.0.4/StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(java.base@9.0.4/StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(java.base@9.0.4/StreamDecoder.java:178)
- locked <0x0000000747d9ea78> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(java.base@9.0.4/InputStreamReader.java:185)
at java.io.BufferedReader.fill(java.base@9.0.4/BufferedReader.java:161)
at java.io.BufferedReader.readLine(java.base@9.0.4/BufferedReader.java:326)
- locked <0x0000000747d9ea78> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(java.base@9.0.4/BufferedReader.java:392)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Common-Cleaner" #9 daemon prio=8 os_prio=31 tid=0x00007f974e00a000 nid=0xa203 in Object.wait() [0x000070000c30a000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(java.base@9.0.4/Native Method)
- waiting on <0x0000000747f37610> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@9.0.4/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x0000000747f37610> (a java.lang.ref.ReferenceQueue$Lock)
at jdk.internal.ref.CleanerImpl.run(java.base@9.0.4/CleanerImpl.java:148)
at java.lang.Thread.run(java.base@9.0.4/Thread.java:844)
at jdk.internal.misc.InnocuousThread.run(java.base@9.0.4/InnocuousThread.java:122)
"Sweeper thread" #8 daemon prio=9 os_prio=31 tid=0x00007f974d81c000 nid=0x5803 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007f974d81b000 nid=0xa503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007f974e005000 nid=0xa603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007f974d81a800 nid=0xa803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f974e01a800 nid=0x5603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f974d041800 nid=0x4003 in Object.wait() [0x000070000bc75000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@9.0.4/Native Method)
- waiting on <0x0000000747f0d078> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@9.0.4/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x0000000747f0d078> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@9.0.4/ReferenceQueue.java:172)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@9.0.4/Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f974d040800 nid=0x4103 waiting on condition [0x000070000bb72000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@9.0.4/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@9.0.4/Reference.java:174)
at java.lang.ref.Reference.access$000(java.base@9.0.4/Reference.java:44)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@9.0.4/Reference.java:138)
"VM Thread" os_prio=31 tid=0x00007f974e884000 nid=0x4303 runnable
"GC Thread#0" os_prio=31 tid=0x00007f974e80d800 nid=0x2a03 runnable
"GC Thread#1" os_prio=31 tid=0x00007f974e80e800 nid=0x5303 runnable
"GC Thread#2" os_prio=31 tid=0x00007f974d80c800 nid=0x2b03 runnable
"GC Thread#3" os_prio=31 tid=0x00007f974d000800 nid=0x2c03 runnable
"G1 Main Marker" os_prio=31 tid=0x00007f974e835800 nid=0x4803 runnable
"G1 Marker#0" os_prio=31 tid=0x00007f974d80d800 nid=0x4503 runnable
"G1 Refine#0" os_prio=31 tid=0x00007f974e80f800 nid=0x4a03 runnable
"G1 Refine#1" os_prio=31 tid=0x00007f974d80d000 nid=0x4c03 runnable
"G1 Refine#2" os_prio=31 tid=0x00007f974e80f000 nid=0x4e03 runnable
"G1 Refine#3" os_prio=31 tid=0x00007f974e806800 nid=0x5003 runnable
"G1 Young RemSet Sampling" os_prio=31 tid=0x00007f974e810800 nid=0x2f03 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007f974e079800 nid=0x5c03 waiting on condition
JNI global references: 421
Heap
garbage-first heap total 131072K, used 10240K [0x0000000740000000, 0x0000000740100400, 0x00000007c0000000)
region size 1024K, 11 young (11264K), 0 survivors (0K)
Metaspace used 8824K, capacity 9274K, committed 9472K, reserved 1058816K
class space used 832K, capacity 927K, committed 1024K, reserved 1048576K
全线程转储Java热点(TM)64位服务器VM(9.0.4+11混合模式):
“DestroyJavaVM”#16 prio=5 os_prio=31 tid=0x00007f974e06d000 nid=0x2503等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“pool-1-thread-2”#15优先级=5 os_优先级=31 tid=0x00007f974e06c000 nid=0x6003等待条件[0x000070000c819000]
java.lang.Thread.State:等待(停车)
在jdk.internal.misc.Unsafe.park(java。base@9.0.4/本机方法)
-停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
在java.util.concurrent.locks.LockSupport.park(java。base@9.0.4/LockSupport.java:194)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java。base@9.0.4/AbstractQueuedSynchronizer.java:2062)
在java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java。base@9.0.4/ScheduledThreadPoolExecutor.java:1119)
在java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java。base@9.0.4/ScheduledThreadPoolExecutor.java:848)
在java.util.concurrent.ThreadPoolExecutor.getTask(java。base@9.0.4/ThreadPoolExecutor.java:1092)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(java。base@9.0.4/ThreadPoolExecutor.java:1152)
在java.util.concurrent.ThreadPoolExecutor$Worker.run(java。base@9.0.4/ThreadPoolExecutor.java:641)
在java.lang.Thread.run(java。base@9.0.4/Thread.java:844)
“pool-1-thread-1”#14优先级=5 os_优先级=31 tid=0x00007f974e8a9800 nid=0x5e03等待条件[0x000070000c716000]
java.lang.Thread.State:等待(停车)
在jdk.internal.misc.Unsafe.park(java。base@9.0.4/本机方法)
-停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
在java.util.concurrent.locks.LockSupport.park(java。base@9.0.4/LockSupport.java:194)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java。base@9.0.4/AbstractQueuedSynchronizer.java:2062)
在java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java。base@9.0.4/ScheduledThreadPoolExecutor.java:1119)
在java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(java。base@9.0.4/ScheduledThreadPoolExecutor.java:848)
在java.util.concurrent.ThreadPoolExecutor.getTask(java。base@9.0.4/ThreadPoolExecutor.java:1092)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(java。base@9.0.4/ThreadPoolExecutor.java:1152)
在java.util.concurrent.ThreadPoolExecutor$Worker.run(java。base@9.0.4/ThreadPoolExecutor.java:641)
在java.lang.Thread.run(java。base@9.0.4/Thread.java:844)
“服务线程”#11守护进程优先级=9 os\U优先级=31 tid=0x00007f974d827000 nid=0xa003可运行[0x0000000000000000]
java.lang.Thread.State:可运行
“监视器控制中断”#10守护进程优先级=5 os_优先级=31 tid=0x00007f974e078800 nid=0x5903可运行[0x00007000C40D000]
java.lang.Thread.State:可运行
在java.net.SocketInputStream.socketRead0(java。base@9.0.4/本机方法)
在java.net.SocketInputStream.socketRead(java。base@9.0.4/SocketInputStream.java:116)
在java.net.SocketInputStream.read(java。base@9.0.4/SocketInputStream.java:171)
在java.net.SocketInputStream.read(java。base@9.0.4/SocketInputStream.java:141)
在sun.nio.cs.StreamDecoder.readBytes(java。base@9.0.4/StreamDecoder.java:284)
在sun.nio.cs.StreamDecoder.implRead(java。base@9.0.4/StreamDecoder.java:326)
在sun.nio.cs.StreamDecoder.read(java。base@9.0.4/StreamDecoder.java:178)
-锁定(java.io.InputStreamReader)
在java.io.InputStreamReader.read(java。base@9.0.4/InputStreamReader.java:185)
在java.io.BufferedReader.fill(java。base@9.0.4/BufferedReader.java:161)
在java.io.BufferedReader.readLine(java。base@9.0.4/BufferedReader.java:326)
-锁定(java.io.InputStreamReader)
在java.io.BufferedReader.readLine(java。base@9.0.4/BufferedReader.java:392)
位于com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
对象中的“通用清理器”#9守护进程优先级=8 os_优先级=31 tid=0x00007f974e00a000 nid=0xa203。等待()
java.lang.Thread.State:定时等待(在对象监视器上)
在java.lang.Object.wait(java。base@9.0.4/本机方法)
-等待(java.lang.ref.ReferenceQueue$Lock)
在java.lang.ref.ReferenceQueue.remove(java。base@9.0.4/ReferenceQueue.java:151)
-等待在wait()中重新锁定(一个java.lang.ref.ReferenceQueue$lock)
在jdk.internal.ref.CleanerImpl.run(java。base@9.0.4/CleanerImpl.java:148)
在java.lang.Thread.run(java。base@9.0.4/Thread.java:844)
在jdk.internal.misc.InnocuousThread.run(java。base@9.0.4/InnocuousThread.java:122)
“清理线程”#8守护进程优先级=9 os_优先级=31 tid=0x00007f974d81c000 nid=0x5803可运行[0x0000000000000000]
java.lang.Thread.State:可运行
“C1编译器线程2”#7守护进程优先级=9 os#优先级=31 tid=0x00007f974d81b000 nid=0xa503等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
没有编译任务
“C2编译器线程1”#6守护进程优先级=9 os#优先级=31 tid=0x00007f974e0050