2013-01-06 22 views
18

tôi có lớp học này để tạo một thread trong JavaLàm cách nào để lấy tên chuỗi trong Java một cách chính xác?

package org.vdzundza.forms; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 

public class DrawThread extends Thread { 
    private static final int THREAD_SLEEP = 500; 
    public CustomShape shape; 
    private Graphics g; 

    public DrawThread(CustomShape shape, Graphics g) { 
     this.shape = shape; 
     this.g = g; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       Thread.sleep(THREAD_SLEEP); 
       Graphics2D g2d = (Graphics2D) g; 
       g2d.setColor(this.shape.getColor()); 
       g2d.fill(this.shape.getShape()); 
       System.out.println(String.format("execute thread: %s %s", 
         Thread.currentThread().getName(), this.getName())); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Giao diện điều khiển hiển thị các văn bản sau đây như một đầu ra

execute thread: red rectangle Thread-2 
execute thread: yellow ellipse Thread-3 

Mã của tôi mà tạo ra các chủ đề mới:

customShapes[0] = new CustomShape(
new Rectangle2D.Float(10, 10, 50, 50), Color.RED, 
    "red rectangle"); 
customShapes[1] = new CustomShape(new Ellipse2D.Float(70, 70, 50, 50), 
Color.YELLOW, "yellow ellipse"); 
for (CustomShape cshape: customShapes) { 
    Thread t = new Thread(new DrawThread(cshape, this.getGraphics()), 
    cshape.getName()); 
    threads.add(t); 
    t.start(); 
} 

Câu hỏi của tôi là: Tại sao Thread.currentThread().getName() trả về tên luồng chính xác trong khi this.getName() trả về tên khác?

Trả lời

39

Tại sao Thread.currentThread().getName() trả lại tên chính xác trong khi this.getName() trả lại tên khác?

lớp DrawThread bạn extends Thread nhưng sau đó bạn khởi động nó bằng cách gọi:

new Thread(new DrawThread(...)); 

Đây không phải là chính xác. Điều đó có nghĩa là chuỗi thực tế được tạo là không phải cùng một số Thread từ DrawThread. DrawThread nên triển khai các chủ đề mở rộng Runnablekhông mở rộng. Mã của bạn hoạt động vì Thread cũng là một Runnable.

public class DrawThread implements Runnable { 

Bởi vì có hai đối tượng chủ đề, khi bạn gọi this.getName() trên đối tượng DrawThread đó không phải là chủ đề đó thực sự là chạy nên tên của nó không được thiết lập đúng cách. Chỉ có tên của chủ đề gói được đặt. Bên trong mã DrawThread, bạn nên gọi Thread.currentThread().getName() để lấy tên thật của chuỗi đang chạy.

Cuối cùng, lớp học của bạn có thể là DrawRunnable nếu nó implements Runnable. :-)

8

Bạn đang chuyển một phiên bản của DrawThread tới một hàm tạo Thread(Runnable). Nó không quan tâm rằng lớp học của bạn mở rộng Thread; nó chỉ quan tâm rằng nó implements Runnable.

Chuỗi bắt đầu là chủ đề được tạo bởi new Thread(...) — và bạn không đặt tên trên tên đó.

Nói chung, việc mở rộng Thread là thực hành không tốt và phải luôn tránh. Bạn đã gần như ở đó vì bạn không start phiên bản lớp học của bạn, nhưng chuyển nó sang một cá thể Thread riêng biệt.

3

Có hai đối tượng liên quan, đối tượng DrawThread chứa phương thức chạy và Chủ đề mới được tạo bằng cách sử dụng nó làm Runnable.

this.getName lấy tên của DrawThread chưa được bắt đầu. Chủ đề hiện tại là chủ đề bạn đã bắt đầu.

2

gọi đơn giản:

new DrawThread().start(); 

để bắt đầu mới Chủ đề

DrawThread drawThread;    // declare object of class DrawThread 
drawThread = new DrawThread();  // instantiate object of class DrawThread 
drawThread.start();     // call start to start DrawThread 

(DrawThread được mở rộng lớp Thread) để bao gồm:

public synchronized void start() { 
     checkNotStarted(); 

     hasBeenStarted = true; 

     nativeCreate(this, stackSize, daemon); // here Thread is created 
    } 

u gọi là ike PUT THREAD BÊN TRONG THREAD (AS RUNNABLE) bằng cách gọi:

public Thread(Runnable runnable) { 
    create(null, runnable, null, 0); 
} 
Các vấn đề liên quan