Java多线程程序挂起
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程程序挂起相关的知识,希望对你有一定的参考价值。
我有一个Java生产者和消费者示例的简单变体。我认为应该可以,但是挂起了。我最初认为这可能是某种形式的死锁,但是当我查看线程转储时,它似乎陷入了无限循环的中间。无论如何,我不明白为什么程序的行为如此奇怪。
public class ProducerConsumer { public static void main(String[] args) { Buffer buffer = new Buffer(7); Producer producer = new Producer(buffer); Consumer consumer = new Consumer(buffer); producer.start(); consumer.start(); } } class Buffer{ private char [] buffer; private int count = 0, in = 0, out = 0; private final Object object1 = new Object(); Buffer(int size){ buffer = new char[size]; } public void put (char c) { while(count == buffer.length) ; synchronized(object1) { System.out.println("Producing" + c + "..."); buffer[in] = c; in = (in + 1) % buffer.length; count++; } } public char get() { while(count == 0) ; char c = buffer[out]; synchronized(object1) { out = (out + 1) % buffer.length; count--; System.out.println("Consuming" + c + "..."); } return c; } } class Producer extends Thread { private Buffer buffer; Producer(Buffer b){ buffer = b; } public void run() { for(int i = 0; i < 10; i++) { buffer.put((char) ('A' + i%26 )); } } } class Consumer extends Thread { private Buffer buffer; Consumer(Buffer b){ buffer = b; } public void run() { for(int i = 0; i < 10; i++) { buffer.get(); } } }
这是程序输出及其线程转储。
c:Temp t>java ProducerConsumer ProducingA... ConsumingA... ProducingB... ConsumingB... ProducingC... ConsumingC... ProducingD... ConsumingD... ProducingE... ConsumingE... ProducingF... ConsumingF... ProducingG... ConsumingG... ProducingH... ConsumingH... ProducingI... ProducingJ... 2019-12-08 22:28:51 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode): "DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000002761800 nid=0x3990 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Thread-1" #12 prio=5 os_prio=0 tid=0x000000003a12a800 nid=0x36f0 runnable [0x000000003b04f000] java.lang.Thread.State: RUNNABLE at Buffer.get(ProducerConsumer.java:36) at Consumer.run(ProducerConsumer.java:71) "Service Thread" #10 daemon prio=9 os_prio=0 tid=0x000000003a0ff000 nid=0x30a4 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread3" #9 daemon prio=9 os_prio=2 tid=0x000000003a05a000 nid=0x3890 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000003a057000 nid=0x16a4 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000003a055000 nid=0x4b4 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000003a04d800 nid=0x4160 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000039ff9000 nid=0x1028 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000039ff7800 nid=0x4f80 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000039fe1800 nid=0x21c in Object.wait() [0x000000003a5be000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000066c408ed8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x000000066c408ed8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216) "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000039fe0800 nid=0x4588 in Object.wait() [0x000000003a4bf000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000066c406c00> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x000000066c406c00> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=2 tid=0x00000000381e9800 nid=0x5418 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002776800 nid=0x2580 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002778000 nid=0x4c98 runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000277a000 nid=0x560c runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000277b800 nid=0x3e78 runnable "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x000000000277d800 nid=0x1f24 runnable "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002780000 nid=0x5074 runnable "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002783000 nid=0x3d88 runnable "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002784000 nid=0x4d18 runnable "VM Periodic Task Thread" os_prio=2 tid=0x000000003a11c800 nid=0x3f8c waiting on condition JNI global references: 5 Heap PSYoungGen total 304640K, used 31335K [0x000000066c400000, 0x0000000681800000, 0x00000007c0000000) eden space 261120K, 12% used [0x000000066c400000,0x000000066e299c00,0x000000067c300000) from space 43520K, 0% used [0x000000067ed80000,0x000000067ed80000,0x0000000681800000) to space 43520K, 0% used [0x000000067c300000,0x000000067c300000,0x000000067ed80000) ParOldGen total 696320K, used 0K [0x00000003c4c00000, 0x00000003ef400000, 0x000000066c400000) object space 696320K, 0% used [0x00000003c4c00000,0x00000003c4c00000,0x00000003ef400000) Metaspace used 2642K, capacity 4492K, committed 4864K, reserved 1056768K class space used 283K, capacity 388K, committed 512K, reserved 1048576K
任何提示将不胜感激。
我有一个Java生产者和消费者示例的简单变体。我认为应该可以,但是挂起了。我最初认为这可能是某种形式的死锁,但是当我查看线程转储时,它是...
答案
当您的使用者线程在生产者线程之前开始使用时,将出现上述情况。您可以在其中进行一些睡眠来模拟它。
以上是关于Java多线程程序挂起的主要内容,如果未能解决你的问题,请参考以下文章
Java 多线程 :入门- 线程间协作:挂起当前线程(wait)与通知其他线程继续执行(notify notifyAll)