xin lỗi nếu điều này cực kỳ rõ ràng hoặc đã được trả lời ở nơi khác. Tôi đã không thể tìm thấy bất cứ điều gì. Tôi có mã sau:Sự nhầm lẫn đồng bộ hóa Java
public class SimpleThread extends Thread {
public static Integer sharedVal = 0;
public SimpleThread() {
}
@Override
public void run() {
while(true) {
iterator();
}
}
public void theSleeper() {
System.out.println("Thread: " + this.getId() + " is going to sleep!");
try {
this.sleep(5000);
} catch(Exception e) {
}
}
public void iterator() {
synchronized(sharedVal) {
System.out.println("Iterating sharedVal in thread: " + this.getId());
sharedVal++;
System.out.println(sharedVal);
theSleeper();
System.out.println("Thread : " + getId() + " is done sleeping, trying to iterate again...");
}
}
}
Tôi tạo hai trường hợp của lớp SimpleThread này và thực thi các phương thức chạy. Tôi sẽ mong đợi để xem một cái gì đó như: Chủ đề 9 incrementing ... Chủ đề 9 ngủ ... (sau 5 giây) Thread 10 incrementing .... Chủ đề 10 ngủ .... Tôi mong đợi điều này bởi vì tôi đang khóa phương thức lặp để chỉ có một luồng tại một thời điểm có thể nhập nó. Điều gì xảy ra thay vào đó là cả hai luồng đều tăng lên, và sau đó cả hai chờ 5 giây. Điều này lặp đi lặp lại mãi mãi. Tôi đang thiếu gì ở đây để tôi có được hành vi mong đợi? Cảm ơn rất nhiều!
EDIT: Tôi đã tạo một biến tĩnh công cộng mới: public static Object theLock = new Object(). Bây giờ, trong phương thức iterator, tôi đã đồng bộ hóa (theLock). Đầu ra bây giờ là nhiều như tôi mong đợi, bởi vì khóa không bao giờ thay đổi. Tuy nhiên, bây giờ chỉ có chủ đề 9 mới được đưa vào phương thức. Dường như chủ đề 10 đang đói, và không bao giờ có một lượt. Điều này có vẻ lạ. Nó không chỉ là một vài lần, nó luôn luôn chỉ thread 9 lặp đi lặp lại và ngủ. Tôi nghĩ rằng nó sẽ là 9, 10, 9, 10. Hoặc có lẽ một phân phối ngẫu nhiên như 9, 10, 10, 10, 9, 10, 9, 9, 10, v.v.
EDIT2: Tôi hiểu xảy ra bây giờ. Chủ đề 9 có khóa. Chủ đề 10 cố gắng nhập hàm, nhưng immedietly nói để chờ đợi. Sau khi hàm hoàn thành, nó vẫn có thể là Thread 9s. Chủ đề 9 sau đó reaqquires khóa, và chu kỳ tiếp tục. Cửa sổ thời gian cho thread 10 để có được lượt là rất nhỏ, và nếu nó đã có được một lần lượt nó sẽ có khả năng chết đói 9. Điều đó đang được nói, đặt yield() sau khi khối đồng bộ trong iterator() dường như không làm cho nó nhiều hơn hội chợ. Tôi đọc các ý kiến trên phương pháp, và lịch trình có thể trong thực tế bỏ qua năng suất().
autoboxing là ma quỷ –
Hahaha, có vẻ như nó có thể là có vấn đề! :) – user2045279