你的位置:首页 > Java教程

[Java教程]关于Thread与runnable


关于线程的的实现有两种,一种是实现Runnable接口,一种是继承Thread。最近深入了解了一下,做下笔记。

1. 首先一个问题是实现线程优先考虑用哪种方式实现?

    优先考虑使用实现Runnable接口,原因如下:

       a. java中只能实现单继承,有一定的局限性

 

2. 启动线程一定要通过start()方法,run()方法不能启动。

    

public class TestThreadInit {    public static void main(String[] args) {    //System.out.println("主线程:"+Thread.currentThread().getName());    MyThread t = new MyThread("TESTTHREAD");    t.start();  }    static class MyThread extends Thread{    public MyThread(String string) {      super(string);    }    @Override    public void run() {      System.out.println(Thread.currentThread().getName());      System.out.println("测试");    }  }}

上面的代码为正常启动线程,若将start方法换为run方法,输出的线程名都会变为主线程。jdk官方官方文档也有描述:

          Causes this thread to begin execution; the Java Virtual Machine calls the <code>run</code> method of this thread.

run方法会通过虚拟机进行调用。

 

3. 多次调用start()方法会有什么影响?

   这个可以通过源代码看出。

 1  public synchronized void start() { 2     /** 3    * This method is not invoked for the main method thread or "system" 4    * group threads created/set up by the VM. Any new functionality added  5    * to this method in the future may have to also be added to the VM. 6    * 7    * A zero status value corresponds to state "NEW". 8     */ 9     if (threadStatus != 0 || this != me)10       throw new IllegalThreadStateException();11     group.add(this);12     start0();13     if (stopBeforeStart) {14     stop0(throwableFromStop);15   }16   }

其中threadStatus 会记录线程状态,若多次调用此方法,会抛出IllegalThreadStateException。

 

 4.Thread 与Runable联系

     a. Thread 实现了Runable接口

public class Thread implements Runnable {}

    在Thread类中引用了Runable

 /* What will be run. */  private Runnable target;

  Thread的构造函数函数都会调用init方法

public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);}private void init(ThreadGroup g, Runnable target, String name,           long stackSize){}

  run()方法实现

 

 public void run() {  if (target != null) {    target.run();  }  }

若使用extend方式创建线程,target对象为null,这时是通过调用重写继承Thread的子类run方法实现,若使用实现runable接口实现,是通过target对象的run方法实现 。

  

 

 

如有问题,请多多指教。

未完,待续。。。。。。。