2015-04-14 30 views
15

Tôi có một chương trình Java lấy CPU 100%, nhưng dường như không làm gì cả.Vòng lặp vô hạn trong EventQueue.isDispatchThread()

Nếu tôi lấy một bãi chứa chuỗi, có 4 chủ đề (trong số 5 hồ bơi) đang đợi để khóa.

"Incoming WorkPool 5" - Thread [email protected] 
    java.lang.Thread.State: WAITING 
    at sun.misc.Unsafe.park(Native Method) 
    - waiting to lock <7212149b> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) owned by "Incoming WorkPool 3" [email protected] 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197) 
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214) 
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290) 
    at java.awt.EventQueue.isDispatchThreadImpl(EventQueue.java:1019) 
    at java.awt.EventQueue.isDispatchThread(EventQueue.java:1014) 

Các chủ đề họ đang chờ đợi là Runnable

"Incoming WorkPool 3" - Thread [email protected] 
    java.lang.Thread.State: RUNNABLE 
    at java.awt.EventQueue.isDispatchThreadImpl(EventQueue.java:1024) 
    at java.awt.EventQueue.isDispatchThread(EventQueue.java:1014) 

Đây là JDK 7.0.25, vì vậy có vẻ như một thread đang bị mắc kẹt trên

EventQueue next = eq.nextQueue; 
while (next != null) { 
    eq = next; 
    next = eq.nextQueue; 
} 

Có hai luồng AWT EventQueue , cố gắng để có được cùng một pushpoplock.

Máy ảo hoạt động như một dịch vụ, do đó, nó không nên cố gắng thực hiện công việc AWT, nhưng nó được thực hiện bởi một thư viện mà tôi đang sử dụng.

Bất kỳ ý tưởng nào? Tôi có thể ngăn điều này xảy ra không?

Cảm ơn!

+0

1. bạn có nghe nói về SecondaryLoop, 2. nhưng "lấy 100% cpu, nhưng dường như không làm gì cả." nói về JProfiler, 3. không có SSCCE/MCVE isn 'answerable, 4. 'java.awt.EventQueue.isDispatchThreadImpl (EventQueue.java: 1019) nói về isEventDispatchThread trả về false', hoặc các sự kiện được thực hiện trong EDT không có doanh nghiệp ở đó 5. không có ý tưởng, không có sự kiện từ EDT hiện tại hoặc ngoại lệ từ RepaintManager – mKorbel

+0

1) Tôi chưa từng nghe về SecondaryLoop trước đây. Tôi đã nhìn nó lên nhưng bản thân tôi không sử dụng AWT, đó là một thư viện tôi sử dụng mà gọi phương thức. 2) Tôi đã không sử dụng JProfiler, tôi đã sử dụng JVisualVM, nó cung cấp cho tôi với threaddump tôi đã hiển thị các đoạn của. 3) Tôi không thể tái tạo nó thật không may. Đó là một vấn đề tôi có trong sản xuất, tất cả những gì tôi có là kết xuất chuỗi, vì vậy tôi không thể cung cấp SSCCE. 4-5) Tôi sợ tôi không hiểu những điều này. –

+1

Ai đang đặt eq.nextQueue thành null? Nếu không có ai thiết lập nó thì vòng lặp sẽ chạy vô hạn và CPU 100% là có thể. Nếu có và nếu nó được thực hiện bởi một số chủ đề khác thì sq.nextQueue nên dễ bay hơi. Nếu không thread này có thể không chọn giá trị kể từ khi thread có thể được cache giá trị của eq.nextQueue nơi vòng lặp sẽ chạy vô hạn một lần nữa và CPU 100% có thể. – Eranda

Trả lời

0

Sự cố của bạn là sự cố bế tắc (see wikipeida).

Deadlock situation here Như bạn thấy ở trên, hai EventQueues của bạn (ở đây R1 và R2) đang ở trong một tình huống bế tắc - mỗi người trong số họ đã tuyên bố một tài nguyên và không thể chạy tiếp tục trong khi kia đã tuyên bố các tài nguyên khác. Cả hai đang chờ đợi nhau vô tận.

Bạn có thể giải quyết vấn đề này với các cách tiếp cận khác nhau:

Cố gắng thay đổi thư viện, bạn nói đúng rằng một thư viện không nên cố gắng làm AWT thứ nếu nó không phải là một thư viện liên quan chặt chẽ với AWT. Thỉnh thoảng có nhiều thư viện trên các nền tảng như github, tôi chắc chắn bạn tìm thấy một thư viện khác để thay thế thư viện của bạn gây ra lỗi.

Nếu bạn có thể chỉnh sửa mã của mình để thêm giám sát, bạn cũng có thể ngăn chặn mọi deadlocks.

synchronized(lock){ 
EventQueue next = eq.nextQueue; 
while (next != null) { 
    eq = next; 
    next = eq.nextQueue; 
} 
lock.notifyAll(); 
} 
+0

Đoạn mã trên là một phần của Java SDK (java.awt.EventQueue.isDispatchThreadImpl (EventQueue.java:1024)), không có cách nào tôi có thể - hoặc muốn - thay đổi mã đó. –

1

Có khả năng nào là push(EventQueue newEventQueue) được chương trình ứng dụng của bạn gọi và đẩy cùng một eventQueue không? Nếu có, thì thisnextQueue của nó sẽ là các đối tượng tương tự và chúng sẽ chạy trong một CPU tiêu thụ vòng lặp vô tận tới 100%.

Từ theo dõi ngăn xếp, rõ ràng là ít nhất một chuỗi đang chạy. Vì vậy, nó không phải là một câu hỏi của DEADLOCK.

Từ gợi ý mức tiêu thụ CPU 100% và trạng thái của nó là RUNNABLE, rõ ràng là nó đang thực hiện vòng lặp vô hạn.

Mã có thể đi vào vòng lặp vô hạn nếu và chỉ khi thì nextQueue có giá trị đã có trong chuỗi (hoặc this). Nó rất có thể là một vấn đề ứng dụng. Cảm ơn.

+0

Tôi không bao giờ nghĩ về điều này, nhưng nó thực sự là có thể thư viện tôi sử dụng không EventQueue.push này. Nó không phải là một thư viện nguồn mở, vì vậy tôi sẽ phải kiểm tra với họ. –

Các vấn đề liên quan