là hợp pháp đối với một chuỗi để gọi this.start() bên trong hàm tạo riêng của nó? và nếu vậy thì những vấn đề tiềm ẩn có thể gây ra điều gì? Tôi hiểu rằng đối tượng sẽ không được khởi tạo đầy đủ cho đến khi hàm tạo đã chạy để hoàn thành nhưng ngoài việc này còn có bất kỳ vấn đề nào khác không?gọi thread.start() trong hàm tạo riêng của nó
Trả lời
Đó là hợp pháp nhưng không khôn ngoan. Phần Thread của instance sẽ được khởi tạo hoàn toàn, nhưng constructor của bạn có thể không. Có rất ít lý do để mở rộng Chủ đề, và để kéo các thủ thuật như thế này sẽ không giúp mã của bạn.
Tôi giả định rằng bạn muốn thực hiện điều này để làm cho mã của bạn ít tiết; thay vì nói
Thread t = new CustomThread();
t.start();
activeThreads.add(t);
bạn chỉ có thể nói
activeThreads.add(new CustomThread());
Tôi cũng giống như có ít rườm rà, nhưng tôi đồng ý với trả lời khác mà bạn không nên làm điều này. Cụ thể, nó phá vỡ quy ước; bất kỳ ai quen thuộc với Java, người đọc ví dụ thứ hai sẽ giả định rằng luồng chưa được bắt đầu. Tệ hơn nữa, nếu họ viết mã luồng riêng của họ tương tác một cách nào đó với bạn, sau đó một số chủ đề sẽ cần phải gọi start
và những người khác sẽ không. Điều này có vẻ không hấp dẫn khi bạn làm việc một mình, nhưng cuối cùng bạn sẽ phải làm việc với những người khác, và tốt để phát triển thói quen viết mã tốt để bạn có thời gian làm việc dễ dàng với người khác và mã được viết với các quy ước tiêu chuẩn.
Tuy nhiên, nếu bạn không quan tâm đến các quy ước và ghét sự dư thừa thêm, hãy tiếp tục; điều này sẽ không gây ra bất kỳ sự cố nào, ngay cả khi bạn cố gọi số start
nhiều lần do nhầm lẫn.
Bằng cách này, nếu ai muốn rườm rà thấp hơn và vẫn giữ các nhà xây dựng với ngữ nghĩa "tiêu chuẩn" của nó, người ta có thể tạo ra một phương pháp nhà máy:
activeThreads.add(CustomThread.newStartedThread());
Nó là "hợp pháp", nhưng tôi nghĩ vấn đề quan trọng nhất là: Một lớp học nên làm một việc và làm tốt.
Nếu lớp học của bạn sử dụng một chuỗi nội bộ, thì sự tồn tại của chuỗi đó sẽ không hiển thị trong API công khai. Điều này cho phép cải tiến mà không ảnh hưởng đến API công khai. Giải pháp: mở rộng Runnable, không phải Thread.
Nếu lớp học của bạn cung cấp chức năng chung, trong trường hợp này, xảy ra để chạy trong một chuỗi, sau đó bạn không muốn giới hạn bản thân để luôn luôn tạo chuỗi. Cùng một giải pháp ở đây: mở rộng Runnable, không phải Thread.
Đối với độ chi tiết ít hơn, tôi thứ hai đề xuất sử dụng phương pháp nhà máy (ví dụ: Foo.createAndRunInThread()).
Vì lý do an toàn cho bộ nhớ, bạn không nên để một tham chiếu đến đối tượng hoặc trường của đối tượng đó đến một chuỗi khác từ bên trong hàm tạo của nó. Giả sử rằng chuỗi tùy chỉnh của bạn có các biến mẫu, bằng cách khởi động nó từ bên trong hàm tạo, bạn được bảo đảm vi phạm các nguyên tắc của Mô hình Bộ nhớ Java. Xem Brian Goetz's Safe Construction Techniques để biết thêm thông tin.
Nhận xét về câu trả lời này? Nó không phải là không chính xác. –
Downvote? Xin vui lòng trang web một nguồn nếu bạn nghĩ rằng điều này là sai. Chính xác. –
Câu trả lời hoàn toàn không được đóng hộp. Trừ khi bạn sử dụng hàm khởi tạo Runnable, bạn có thể tham chiếu 'this' từ bên trong' Thread # run' trước khi hàm khởi tạo hoàn thành, vi phạm các quy tắc an toàn bộ nhớ. Vì vậy, bạn phải cẩn thận. –
Bạn cũng sẽ thấy các vấn đề đáng sợ nếu lớp Thread được thêm lớp con. Trong trường hợp đó, bạn sẽ kết thúc với luồng đang chạy một khi các lối thoát super() và bất kỳ thứ gì mà lớp con có thể làm trong hàm tạo của nó có thể không hợp lệ.
@bill barksdale Nếu chuỗi đã chạy, gọi lại bắt đầu giúp bạn nhận được một IllegalThreadStateException, bạn không nhận được 2 chuỗi.
Pháp lý ... có (với các lời nhắc như đã đề cập ở nơi khác). Có thể tư vấn ... không.
Tôi chỉ là mùi mà bạn chỉ có thể dễ dàng tránh được. Nếu bạn muốn chủ đề của mình tự động bắt đầu, chỉ cần thực hiện như sau: Heinz Kabutz.
public class ThreadCreationTest {
public static void main(String[] args) throws InterruptedException {
final AtomicInteger threads_created = new AtomicInteger(0);
while (true) {
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
{ start(); } // <--- Like this ... sweet and simple.
public void run() {
latch.countDown();
synchronized (this) {
System.out.println("threads created: " +
threads_created.incrementAndGet());
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
};
latch.await();
}
}
}
- 1. Ngăn chặn cuộc gọi của một hàm tạo riêng từ bên trong lớp trong Java
- 2. sử dụng hàm tạo riêng trong lớp
- 3. Trình tạo cuộc gọi Python của cá thể riêng của nó
- 4. DataContractSerializer không gọi hàm tạo của tôi?
- 5. ngữ Javascript: tạo một hàm chỉ để gọi nó
- 6. Khi nào bạn sẽ gọi java's thread.run() thay vì thread.start()?
- 7. Gọi một hàm trong một file riêng biệt trong Python
- 8. gọi hàm tạo bản sao bên trong hàm tạo khác
- 9. Java Spring bean với hàm tạo riêng
- 10. Tại sao một con trỏ thông minh không thể gọi hàm new() cho tôi trong hàm tạo của nó?
- 11. Gọi hàm tạo của cha mẹ trong PHP
- 12. Tại sao đặt hàm tạo của nguyên mẫu cho hàm tạo của nó?
- 13. Tạo một thể hiện của một lớp trong hàm tạo tĩnh của nó - tại sao nó được cho phép?
- 14. Gọi hàm riêng tư trong cùng một trăn lớp
- 15. gọi hàm tạo của một thành viên lớp trong hàm tạo
- 16. C++ Khởi tạo Mảng trong Lệnh gọi hàm hoặc Gọi hàm
- 17. Gọi hàm tạo "siêu lớp" trong JavaScript
- 18. Gọi hàm tạo siêu trong C#
- 19. Lợi thế của việc sử dụng Thread.Start vs QueueUserWorkItem
- 20. Gọi hàm tạo như một hàm trong C#
- 21. Gọi hàm tạo lớp con trước hàm tạo cha
- 22. Cách gọi một hàm bên trong chính nó?
- 23. Sử dụng hàm tạo trong một cuộc gọi hàm?
- 24. Gọi đến siêu phải là câu lệnh đầu tiên trong hàm tạo, nhưng nó là
- 25. Tạo một hàm và gọi nó trong một dòng mã C#
- 26. phạm vi của hàm tạo riêng tư trong Lớp lồng nhau
- 27. Phương pháp Varargs thay đổi mảng của người gọi thay vì bản sao của riêng nó?
- 28. Mạng nơron nhân tạo tạo ra kết nối riêng của nó
- 29. Gọi hàm thành viên từ một hàm tạo
- 30. Tại sao tôi có thể gọi hàm tạo riêng từ phạm vi toàn cục?
điều này liên quan đến câu hỏi của OP như thế nào? – subsub