2013-05-13 28 views
18

Gần đây, tôi đã được các nhà phát triển cấp cao cho biết không nên sử dụng Thread.join() để đợi một Chủ đề khác kết thúc. Tôi cũng đã thấy một số câu hỏi như vậy trên SO yêu cầu thay thế để tham gia.Lý do không sử dụng Thread.join()

Trong nghiên cứu của mình, tôi không thể tìm thấy điều gì sai với join(). Trong thực tế nó được sử dụng rộng rãi.

Vì vậy, tôi muốn biết tại sao không sử dụng join()? Điều gì là sai với nó? Nó có khuyến khích lập trình hoặc kiến ​​trúc kém không?

+5

Không có gì sai với nó, nếu bạn cần phải chờ các chủ đề hoàn thành. Đó là những gì nó cho. – xagyg

+1

Tôi giả sử rằng các chuỗi của bạn chưa bao giờ hoàn thành, nó sẽ tạm dừng (không khóa) chủ đề chính vô thời hạn, nhưng đó không phải là vấn đề với 'join', đó là vấn đề với chương trình của bạn. – xagyg

+0

Hãy hỏi các 'nhà phát triển cao cấp' những gì họ đang nói về. Có lẽ những gì họ thực sự có nghĩa là không chờ đợi cho các chủ đề khác để kết thúc ở tất cả. Ai biết? Tại sao bạn hỏi ở đây? – EJP

Trả lời

1

IMO không có gì sai khi tham gia. Bạn chỉ cần cẩn thận để đảm bảo rằng các chủ đề bạn đang chờ đợi trên chấm dứt trong mọi trường hợp. Vì nếu không thì việc thực thi có thể dừng lại mãi mãi. Vì vậy, nếu bạn đang làm cho chủ đề chính chờ đợi trên một số chủ đề bằng cách sử dụng tham gia và các chủ đề không chấm dứt nó có thể gây ra toàn bộ ứng dụng của bạn để đóng băng.

33

Không có gì sai với join(). Nó là tốt như nó được.

Tuy nhiên, đây là lý do tại sao bạn không nên kiến ​​trúc sư ứng dụng của bạn dựa vào tham gia. Trong Java, trừu tượng chính cho các tác vụ đang chạy không phải là Thread nữa. Đó là Executor. Đó là bạn quấn các tác vụ đồng thời là Callable và chỉ cần gửi nó đến một số Executor mà không phải lo lắng về chi tiết thực thi. Đây là cách hoạt động của Executor. Bạn submit hoặc execute a Callable hoặc Runnable tương ứng và không cần chỉ định Chủ đề.

Vì vậy, tôi muốn biết tại sao không sử dụng join()?

Sau đó, đây là lý do của bạn: Vì bạn không tạo hoặc thao tác Chủ đề trong thế giới công nhân, không có điểm nào khi sử dụng join. Hầu hết mọi join đều có thể được thay thế bằng một thứ khác (Future.get, CountDownLatch, Locks, v.v ...).


Lưu ý: Tôi không nói rằng bạn không cần thao tác Chủ đề khi sử dụng Executors. Trong một số trường hợp, tốt hơn nên tạo phân lớp Thread riêng và sau đó có Executor sử dụng chúng thông qua ThreadFactory.

+0

* tốt hơn nên tạo phân lớp Thread của riêng và sau đó có Executor sử dụng chúng thông qua ThreadFactory * điểm của lớp con 'java.lang.Thread' là gì? – bestsss

10

Không có gì sai khi sử dụng Thread.join nói chung, tuy nhiên bạn cần phải rất cẩn thận và biết chủ đề đến từ đâu. Nếu nó đến từ một hồ bơi chủ đề thread - thì bạn đang gặp rắc rối thực sự, bởi vì các chủ đề như vậy đang chạy cho đến khi hồ bơi bị chấm dứt và chia sẻ giữa nhiều công nhân.

1

Khung Fork/Join được giới thiệu trong Java 7. Hãy xem xét sử dụng khung này thay vì Thread.join(). Nói chung, bạn nên sử dụng các lớp từ gói java.util.concurrent. * Nếu có thể, giảm thiểu việc sử dụng các kỹ thuật đồng bộ hóa ban đầu như khối đồng bộ, chờ/thông báo và tham gia. java.util.concurrent mang lại sự linh hoạt hơn nhiều.

+0

* giảm thiểu việc sử dụng các kỹ thuật đồng bộ gốc như khối đồng bộ, chờ/thông báo *, khối đồng bộ hóa chỉ là tốt, đặc biệt. nếu bạn mong đợi w/ganh đua thấp hơn. Khối đồng bộ hóa thường có thể là lựa chọn tốt hơn 'ReentrantLock', xem [CHMv8] (http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/ConcurrentHashMapV8.java? xem = log) chẳng hạn. Doug Lea sẽ trở lại đồng bộ hóa thông thường. khối – bestsss

+0

Cảm ơn bạn đã cung cấp thông tin. – Mikhail

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