2012-10-31 42 views
8

Tôi đang thực sự tìm kiếm một cách dễ dàng hơn để tiêu diệt chuỗi không quan trọng nơi luồng đang chạy. Nhưng hầu hết các giải pháp trong internet chỉ cho tôi để sử dụng cờ boolean để kiểm soát việc thực hiện các chủ đề, nếu tôi muốn dừng thread sau đó đặt biến boolean thành false.Cách Java thread.stop() hoạt động?

Nhưng điều gì sẽ xảy ra nếu nhiệm vụ trong runnable là tác vụ tuyến tính dài, nghĩa là nhiệm vụ không lặp lại? Trong trường hợp đó, nó không phải là dễ dàng như vậy để tạo một vòng lặp 'while' để bao trùm toàn bộ khối nhiệm vụ.

Thật sự rất cám dỗ khi sử dụng Thread.stop nhưng cảnh báo "Không được chấp nhận" có vẻ khá nguy hiểm khi sử dụng. Tôi đã đọc qua bài viết này Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?

nhưng tôi không thể hiểu

Nếu bất kỳ của các đối tượng trước đây được bảo vệ bởi các màn hình đang ở một trạng thái không nhất quán, chủ đề khác bây giờ có thể xem các đối tượng trong một trạng thái không nhất quán. Các đối tượng như vậy được cho là bị hư hỏng.

"Trạng thái không nhất quán" có nghĩa là gì? Tôi đánh giá cao nếu có ai có thể giải thích về điều này.

Tôi muốn mở rộng câu hỏi của mình ở cấp độ thấp hơn, giả sử i = i + 1; trong JVM (có thể là ngôn ngữ assembly), có thể câu lệnh Java này sẽ được chia thành một số hướng dẫn nhỏ hơn, ví dụ như move i ; add i ; get i into memory 0x0101 (Đây là Ví dụ! Tôi hoàn toàn không biết ngôn ngữ lắp ráp!)

Bây giờ, nếu chúng ta gọi thread.stop, nó sẽ dừng ở đâu? Chuỗi sẽ dừng sau câu lệnh Java đã hoàn thành hay có thể ở giữa "ngôn ngữ lắp ráp"? Nếu câu trả lời là câu trả lời thứ hai, có thể đó là lý do chúng tôi đã nói

Các đối tượng như vậy được cho là bị hỏng.

?

Ok, câu hỏi của tôi là loại bối rối, hy vọng ai đó có thể hiểu và giải thích. Cảm ơn trước.

+0

Câu hỏi liên quan http://stackoverflow.com/questions/7291914/java-stop-safety-a-thread-not-using-while-and-boolean-flag –

Trả lời

3

Các "nhà nước không phù hợp" có nghĩa là nhà nước của dữ liệu như ứng dụng của bạn quan tâm đến, tiểu bang mà logic ứng dụng của bạn đã được sản xuất một cách cẩn thận bằng cách làm cho ứng dụng của bạn thread-safe với ổ khóa/màn hình, vv

Hãy tưởng tượng bạn có phương pháp đơn giản này :

public synchronized void doSomething() 
{ 
     count++; 
     average = count/total; 
} 

Phương pháp này, cùng với các phương pháp khác được đồng bộ hóa, vì nhiều chủ đề đang sử dụng đối tượng này. Có lẽ có một

public synchronized AverageAndCount getMeasurement() 
{ 
    return new AverageAndCount(average, count); 
} 

này đảm bảo rằng một sợi không thể đọc được một phép đo không đầy đủ, ví dụ: nếu đo lường hiện nay là trong quá trình đang được tính toán bên trong ví dụ doSomething(), getMeasurement() sẽ chặn/đợi cho đến khi kết thúc.

Bây giờ, hãy tưởng tượng doSomething chạy trong chuỗi và bạn gọi .stop() trên chuỗi đó.

Vì vậy, các chủ đề có thể được dừng lại ngay sau khi nó thực hiện count++;, màn hình đó là tổ chức được mở khóa và phương pháp chấm dứt và average = count/total; không được thực thi,

đó có nghĩa là dữ liệu hiện nay là không phù hợp. Bất cứ ai gọi getMeasurement() sau đó sẽ nhận được dữ liệu không phù hợp. Lưu ý rằng tại thời điểm này nó không phải là rất có liên quan cho dù điều này xảy ra ở cấp java tuyên bố, hoặc ở một mức độ thấp hơn, dữ liệu có thể ở trong một nhà nước không phù hợp mà bạn không thể lý do trong bất kỳ trường hợp nào.

5

"Đối tượng bị hỏng" là khái niệm cấp cao, nó không xảy ra ở cấp JVM. Một lập trình viên thiết kế lớp học của mình với sự an toàn của luồng bằng cách bảo vệ các phần quan trọng bằng khóa. Nó là một bất biến của lớp học của mình mà mỗi phần quan trọng hoặc chạy đầy đủ, hoặc không chạy ở tất cả. Khi bạn stop một chuỗi, một phần quan trọng có thể đã bị gián đoạn ở giữa, do đó làm gián đoạn sự bất biến. Tại thời điểm đó, đối tượng là bị hỏng.

Dừng một chủ đề che giấu nhiều mối nguy hiểm hơn, như không dọn dẹp, không có tài nguyên được mua, vv Nếu một chủ đề không từ bỏ những gì nó đang làm, không có cách nào để dừng lại mà không ảnh hưởng đến toàn bộ ứng dụng . Trong thực tế, bất cứ khi nào một người phải đối mặt với sự cần thiết phải chạy mã người nước ngoài có thể cần phải được hủy bỏ một cách mạnh mẽ, điều này phải được thực hiện trong một quá trình riêng biệt bởi vì giết chết một quá trình ít nhất là làm sạch cấp hệ điều hành và làm tốt hơn nhiều công việc có chứa thiệt hại.

2

Tôi không có chuyên gia nhưng đây là những gì tôi nghĩ. Nếu bạn sử dụng Thread.stop(), bạn gây ra ngoại lệ ThreadDeath sẽ làm cho tất cả các màn hình được phát hành. Vì bạn gây ra một ngoại lệ, bạn đang áp dụng một hành vi không tự nhiên vào trạng thái của sự vật.

Các chủ đề khác dựa vào các màn hình đó có thể nhập vào một tình huống không nhất quán vì chúng không mong đợi nó. Và tôi không nghĩ rằng bạn thậm chí có thể dự đoán thứ tự phát hành màn hình.

2

Tôi tin rằng mối quan tâm là luồng có thể đang ở giữa khối đồng bộ thực hiện cập nhật nhiều bước cho các thành viên của đối tượng. Nếu thread được dừng đột ngột, sau đó một số cập nhật sẽ xảy ra nhưng không xảy ra với người khác và bây giờ trạng thái của đối tượng có thể khiến nó không sử dụng được.

Tôi có nghi ngờ rằng việc xử lý ThreadDeath sẽ phát hành Lock được hỗ trợ bởi AbstractQueuedSynchronizer có thể khiến ứng dụng trên đường dẫn đến một loại bế tắc.

Tại bất kỳ điểm logic trong chuỗi dài của bạn mã bạn chỉ có thể thêm:

if (Thread.interrupted()) { 
    throw new InterruptedException(); 
} 

... điều này sẽ thoát khỏi thực hiện vào thời điểm này nếu nó được xác định rằng Thread.interupt() đã kêu gọi thực hiện Thread dài nhiệm vụ đang chạy.

-1

Đó không phải là cách rõ ràng để ngăn chặn thread.actually không được chấp nhận phương pháp stop() bất cứ khi nào phương thức run() được hoàn thành hoặc bất kỳ ngoại lệ nào xảy ra, sau đó thread là stop.by sử dụng biến cờ boolean .Bydefault "false"

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