2012-11-28 25 views
5

Ok, tôi biết đó là sự hiểu biết xấu probabblly mz về cách đề thực sự làm việc, nhưng cho đến khi một người nào đó giúp tôi hiểu rằng tôi sẽ tin rằng đó là một lỗi :)Chủ đề getName() trả về sai tên

Trong lớp Main của tôi và phương pháp main() của nó tôi có:

public static void main(String args[]){ 
    StoneBucket stoneBucket = new StoneBucket();  
    StonePutter spRunnable = new StonePutter(stoneBucket); 
    StoneThrower stRunnable = new StoneThrower(stoneBucket); 
    StoneThrower stRunnable2 = new StoneThrower(stoneBucket); 

    //Create the Threads that will take the Runnables as arguments 
    Thread puttingThread = new Thread(spRunnable); 
    Thread throwingThread = new Thread(stRunnable); 
    Thread throwingThread2 = new Thread(stRunnable); 

    puttingThread.setName("Putter"); 
    throwingThread.setName("Thrower 1"); 
    throwingThread2.setName("Thrower 2"); 
    [...] 

và sau đó trong lớp StoneThrower của tôi, tôi có

public class StoneThrower implements Runnable{ 

private StoneBucket sb; 
private String name; 

public StoneThrower(StoneBucket _sb){ 
    this.sb = _sb; 
} 

public void run(){ 

    name = Thread.currentThread().getName();   
    System.out.println("T::"+name+" started...");  
    int count = 0;  
    while(true){ 
      [...] 

Khi tôi biên dịch và chạy mã này tôi nhận được:

Screenshot of 2 threads...

Vì vậy, câu hỏi của tôi là tại sao cả hai chủ đề này đều có cùng tên cho currentThread().getName()? Khi chúng được tạo, chúng được chỉ định tên thông qua threadX.setName("XXX") và các lần chạy này được bắt đầu bằng cách gọi threadX.start() ... Ai đó có thể làm rõ cho tôi điều này không?

EDIT: Tôi chấp nhận câu trả lời đúng vì thay đổi stRunnable thành stRunnable2 hành vi như mong đợi. Câu hỏi thực sự là tại sao điều này lại xảy ra. Tôi tạo ra hai chủ đề và bắt đầu chúng một cách riêng biệt. Làm thế nào là nó posibble rằng run() phương pháp (được gọi là một lần khi thread's tạo ra) trả về tên sai?

+0

Bạn có thể gửi các bit của mã nơi bạn đang bắt đầu các chủ đề? – PearsonArtPhoto

Trả lời

9

Điều này xảy ra vì bạn lưu trữ tên chuỗi trong biến mẫu name trong số StoneThrower của mình. Vì đồng thời, chuỗi ghi đè thứ hai giá trị của name mà chuỗi đầu tiên vừa được đặt và cả hai đầu ra đều có cùng giá trị.

Đây là kịch bản của bạn:

1. Thread1#start 
2. Thread2#start 
3. Thread1#runnable#run -> runnable.name = 'Thrower 1' 
4. Thread2#runnable#run -> runnable.name = 'Thrower 2' // overrides 
5. Thread1#runnable#run -> System.out.println(runnable.name) 
6. Thread2#runnable#run -> System.out.println(runnable.name) 
+2

Cuối cùng là một chẩn đoán hợp lý +1 –

+0

Tôi đã thêm một bình luận yêu cầu này.Cảm ơn bạn rất nhiều và xin lỗi @NPE để lấy cờ trả lời đúng: ( – luigi7up

+0

Đã không nhìn thấy toàn bộ việc thực hiện 'StoneThrower' nhưng có lẽ bạn chỉ có thể có một cá thể của nó nếu bạn chuyển' name' thành biến cục bộ. – hoaz

5

Bạn tạo cả bài với cùng Runnable:

Thread throwingThread = new Thread(stRunnable); 
Thread throwingThread2 = new Thread(stRunnable); 
            ^^^^^^^^^^ stRunnable2? 

Bạn lưu trữ tên chủ đề trong một biến thể hiện của đối tượng Runnable. Vì đối tượng được chia sẻ bởi hai luồng, chuỗi thứ hai để thực hiện name = Thread.currentThread().getName() sẽ ghi đè tên của chuỗi đầu tiên bằng tên riêng của nó.

+1

Tạo chủ đề riêng biệt với cùng một Runnable trong chính nó không buộc các chủ đề có cùng tên. Có một cái gì đó đang xảy ra. –

+0

@TedHopp: Trong trường hợp này, nó có. Tên chủ đề được lưu trữ trong một biến mẫu của đối tượng 'Runnable'. Vì đối tượng được chia sẻ bởi hai luồng, chuỗi thứ hai để thực thi 'name = Thread.currentThread(). GetName()' thắng. – NPE

+0

Có, nhưng đó không phải là một phần của câu trả lời của bạn khi tôi đưa ra nhận xét đó. Với bản chỉnh sửa, giờ đây nó kiếm được +1 của tôi. –

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