相关文章推荐
耍酷的企鹅  ·  【计算机系统1 】1 ...·  1 年前    · 
强健的杨桃  ·  Marshal Class ...·  1 年前    · 

多线程原理

相当于玩游戏机, 只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()
调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,
没这个start不行。

start()

start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。

run()

run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。

start() 和 run()的区别说明

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()

start() 和 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()的区别)

文章目录多线程原理start()run()start() 和 run()的区别说明start() 和 run()的区别示例多线程原理相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。调用start()后,线程会被放到等待队列,等待CPU调度,并...
Thread的Start和Run方法区别功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 创建线程的两种方式,继承Thr...
首先需要知道线程的几个状态以及多线程工作方式。 new 一个Thread,线程进入了新建状态,调用start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到 时间片 后就可以开始运行了。start() 会执行线程的相应准备工作,然后自动执行run() 方法的内容,这是真正的多线程工作。 而直接执行run() 方法,会把run 方法当成一个main 线程下的普通方法去执行,并不会在某个线程执行它,所以这并不是多线程工作。 总的来说:调用start 方法方可启动线程并使线程进入就绪状态,而run