相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。 调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点, 没这个start不行。
start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。 记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。
start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。 run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
下面以代码来进行说明。
class MyThread extends Thread{ public void run(){ ... } }; MyThread mythread = new MyThread();mythread.start()会启动一个新线程,并在新线程中运行run()方法。 而mythread.run()则会直接在当前线程中运行run()方法,并不会启动一个新线程来运行run()。
下面,通过一个简单示例演示它们之间的区别。源码如下:
public class Demo { public static void main(String[] args) { Thread mythread=new MyThread("mythread"); System.out.println(Thread.currentThread().getName()+" call mythread.run()"); mythread.run(); System.out.println(Thread.currentThread().getName()+" call mythread.start()"); mythread.start(); } } class MyThread extends Thread{ public MyThread(String name) { super(name); } public void run(){ System.out.println(Thread.currentThread().getName()+" is running"); } };运行结果: 结果说明: (01) Thread.currentThread().getName()是用于获取“当前线程”的名字。当前线程是指正在cpu中调度执行的线程。 (02) mythread.run()是在“主线程main”中调用的,该run()方法直接运行在“主线程main”上。 (03) mythread.start()会启动“线程mythread”,“线程mythread”启动之后,会调用run()方法;此时的run()方法是运行在“线程mythread”上。
start() 和 run()相关源码(基于JDK1.7.0_40) Thread.java中start()方法的源码如下:
public synchronized void start() { // 如果线程不是"就绪状态",则抛出异常! if (threadStatus != 0) throw new IllegalThreadStateException(); // 将线程添加到ThreadGroup中 group.add(this); boolean started = false; try { // 通过start0()启动线程 start0(); // 设置started标记 started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }说明:start()实际上是通过本地方法start0()启动线程的。而start0()会新运行一个线程,新线程会调用run()方法。
private native void start0();Thread.java中run()的代码如下:
public void run() { if (target != null) { target.run(); } }说明:target是一个Runnable对象。run()就是直接调用Thread线程的Runnable成员的run()方法,并不会新建一个线程。
参考: https://www.cnblogs.com/sunflower627/p/4816821.html (Java多线程中start()和run()的区别) https://www.cnblogs.com/skywang12345/p/3479083.html#a2 ( Thread中start()和run()的区别)