多线程——调用start()方法与直接调用run()方法的区别
class MyThread3 extends Thread{ private String title; public MyThread3(String title){ this.title=title; } @Override public void run() { for(int i=0;i<10;i++){ System.out.println(this.title+".x="+i); } } } public class ThreadTest3 { public static void main(String[] args) { MyThread3 mt1=new MyThread3("线程1"); MyThread3 mt2=new MyThread3("线程2"); MyThread3 mt3=new MyThread3("线程3"); mt1.run(); mt2.run(); mt3.run();//只是顺序执行,不是多线程 mt1.start(); mt2.start(); mt3.start();//调用Thread类的start方法才是正确启动多线程的方式 } }
调用run方法的结果是:
线程1.x=0
线程1.x=1
线程1.x=2
线程1.x=3
线程1.x=4
线程1.x=5
线程1.x=6
线程1.x=7
线程1.x=8
线程1.x=9
线程2.x=0
线程2.x=1
线程2.x=2
线程2.x=3
线程2.x=4
线程2.x=5
线程2.x=6
线程2.x=7
线程2.x=8
线程2.x=9
线程3.x=0
线程3.x=1
线程3.x=2
线程3.x=3
线程3.x=4
线程3.x=5
线程3.x=6
线程3.x=7
线程3.x=8
线程3.x=9
调用start方法的结果是:
线程2.x=0
线程2.x=1
线程2.x=2
线程2.x=3
线程2.x=4
线程3.x=0
线程3.x=1
线程3.x=2
线程3.x=3
线程3.x=4
线程3.x=5
线程3.x=6
线程3.x=7
线程3.x=8
线程3.x=9
线程1.x=0
线程1.x=1
线程1.x=2
线程1.x=3
线程1.x=4
线程1.x=5
线程1.x=6
线程1.x=7
线程1.x=8
线程1.x=9
线程2.x=5
线程2.x=6
线程2.x=7
线程2.x=8
线程2.x=9
查看Thread类的start方法的源码:
public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }
首先,这个方法会抛出一个异常"IllegalThreadStateException",按照原来的处理方式应该使用throws声明,或者直接在方法中进行try...catch,在这里说明它是一个RuntimeException的子类这个异常只是在重复启动了多线程时才会抛出,所以一个线程对象只能够启动一次。
然后,在start方法里调用了一次start0方法,这个方法是一个只声明未定义的方法,并且使用了native关键字进行定义native指的是调用本机的原生系统函数。所以,调用start方法,会告诉JVM去分配本机系统的资源,才能实现多线程。