2012-04-18 78 views
8

Tôi có một số mã Vaadin chặn rất thường xuyên ở đây, và tôi không có ý tưởng những gì các vấn đề có thể là:vòng lặp vô hạn trong java.util.HashMap

Thread 7892: (state = IN_JAVA) 
- java.util.HashMap.getEntry(java.lang.Object) @bci=61, line=349 (Compiled frame; information may be imprecise) 
- java.util.HashMap.containsKey(java.lang.Object) @bci=2, line=335 (Compiled frame) 
- java.util.HashSet.contains(java.lang.Object) @bci=5, line=184 (Compiled frame) 
- com.vaadin.ui.Table.unregisterPropertiesAndComponents(java.util.HashSet, java.util.HashSet) @bci=85, line=1693 (Compiled frame) 
- com.vaadin.ui.Table.refreshRenderedCells() @bci=992, line=1641 (Compiled frame) 
- com.vaadin.ui.Table.valueChange(com.vaadin.data.Property$ValueChangeEvent) @bci=23, line=2897 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer.firePropertyValueChange(com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=140, line=553 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer.access$1000(com.vaadin.data.util.IndexedContainer, com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=2, line=64 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(java.lang.Object) @bci=202, line=915 (Compiled frame) 
- com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread.insertNewPersonIntoTable(com.aimprosoft.wavilon.model.Person, com.vaadin.ui.HorizontalLayout, com.aimprosoft.wavilon.ui.menuitems.CallContent, com.vaadin.ui.Table) @bci=924, line=208 (Interpreted frame) 
- com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread$RepaintTableThread.run() @bci=622, line=446 (Compiled frame) 

ai đó có thể đề xuất cách nào để tiếp tục gỡ rối vấn đề này? Vấn đề xảy ra rất hiếm khi, và rất khó để tái sản xuất.

+0

bạn có thể lấy một số mã nguồn không? – iMysak

+0

Trong trường hợp này, không cần mã nguồn thực. Tôi đã nhìn thấy dấu vết ngăn xếp này thường xuyên đủ.:) –

+0

@gonvaled Vui lòng xem câu trả lời của tôi, giải thích chi tiết lý do bạn thấy hành vi này. –

Trả lời

15

Dựa vào vị trí của mã, giải thích duy nhất tôi có thể nghĩ là có nhiều luồng truy cập và cập nhật HashMap mà không đồng bộ hóa đúng cách. Điều này có thể khiến cấu trúc dữ liệu của bản đồ bị hỏng và có thể dẫn đến vòng lặp vô hạn.

Tôi không thể nghĩ ra bất kỳ lý do nào khác tại sao java.util.HashMap.getEntry sẽ chặn. Nó không thực hiện bất kỳ đồng bộ hóa hoặc bất kỳ I/O nào.


Roland Illig nhận xét:

Số dòng thực sự gợi ý rằng mã treo tại một trong những e = e.next vòng.

Điều đó hỗ trợ giả thuyết của tôi. Một chuỗi các hoạt động cụ thể trên bảng băm được thực hiện bởi hai (hoặc nhiều) luồng đã dẫn đến việc tạo vòng lặp/chu kỳ trong một trong các chuỗi băm. Tham nhũng này đã xảy ra vì có quá trình đồng bộ hóa không đầy đủ giữa các luồng thực hiện các hoạt động. Đó là loại điều hiếm khi xảy ra, nhưng một khi nó đã xảy ra thì tham nhũng sẽ không biến mất.

Nếu không nhìn sâu vào mã nguồn của Vaadin, tôi không thể cho bạn biết chính xác đó có phải là lỗi Vaadin hay lỗi theo cách bạn đang sử dụng sử dụng Vaadin. Hoặc là giải thích là hợp lý.

CẬP NHẬT

Dựa trên this article (được cung cấp trong một chú thích dưới đây), tôi sẽ nói rằng nó rất có thể là một vấn đề trong cách mà ứng dụng của bạn được đồng bộ hóa (hay không).

+1

Số dòng thực sự cho thấy mã bị treo ở một trong các vòng lặp 'e = e.next'. –

+0

Bạn thực sự đúng rằng công thức của tôi là một chút mâu thuẫn. Ý tôi là: rất * rất khó để tái sản xuất (tôi phải tạo nhiều dữ liệu để kiểm tra căng thẳng và nhấp vào ứng dụng web của tôi một cách ngẫu nhiên để thực hiện điều này), nhưng bất cứ khi nào nó đạt đến tình huống lỗi, * rất thường xuyên * nó đang hiển thị dấu vết stack được hiển thị. Xin lỗi vì sự cẩu thả của tôi, nhưng hôm qua sau một ngày gỡ lỗi dài, tôi cảm thấy hơi thất vọng. – dangonfast

2

Chủ đề nền của bạn có được đồng bộ hóa trên cá thể ứng dụng khi sửa đổi thành phần không? Nếu không, thì đó là vấn đề của bạn.

+0

@gonvaled Khi Artur đang nói bạn * phải * đồng bộ hóa xử lý nền của bạn với cá thể ứng dụng Vaadin hoặc bạn sẽ gặp phải các vấn đề như thế này. Xem bài viết này: http://njbartlett.name/2011/05/25/concurrent-vaadin.html để biết giải pháp và mã ví dụ. – hezamu

7

Vì vậy, những gì bạn đang thực sự nhìn thấy ở đây là một sợi đi vào một vòng lặp vô hạn đánh giá e = e.next

Về bản chất

e.next == e

này xảy ra khi bạn đang đưa vào một HashMap bởi nhiều chủ đề trong một sắp xếp lại bảng.

Hãy nhìn vào liên kết này để biết thêm thông tin

A Beautiful Race Condition

Để giải quyết điều này, hoặc sử dụng một Collections.synchronizedMap hoặc ConcurrentHashMap. Tôi đề nghị cái sau.

+0

Thật không may tôi không thể thay đổi việc thực hiện các thư viện vaadin (tốt, tôi cho rằng tôi có thể, nhưng đó sẽ là quá phức tạp) – dangonfast

+0

@gonvaled Họ có trên github? Bạn có thể mở yêu cầu kéo hoặc có thể có phiên bản mới hơn có bản sửa lỗi. –

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