对于Thread的start()方法和run()方法区别的一点认识

       今天在研究学习ThreaLocal的时候发现一个问题。如下:

我在main方法中新建了两个线程并调用他们的run()方法,并在run()方法里打印当前的线程信息,发现自始至终都只有一个main线程比较疑惑,随后我把run()方法改为start()方法发现这个问题不见了,让我一下意识到start()和run()之间是存在区别的,但是我之前并没有注意到这两个方法的区别。

       先来看下代码吧

public class App {

    public static void main(String[] args)throws Exception {
        User user1 = new User(1, "张三");
        User user2 = new User(2, "李四");
        User user3 = new User(3, "王五");
        UserHolder.set(user3);
        MyThread t1 = new MyThread(user1);
        MyThread t2 = new MyThread(user2);
        t1.run();
        t2.run();
        System.out.println(Thread.currentThread().getName() + "------" + UserHolder.get());
    }

}

class MyThread implements Runnable {

    private User user;

    public MyThread(User user) {
        this.user = user;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName() + "------" + UserHolder.get());
        UserHolder.set(user);
        System.out.println(Thread.currentThread().getName() + "------" + UserHolder.get());
    }
}

 输出结果是这样:

main------User{id=3, uername='王五'}
main------User{id=1, uername='张三'}
main------User{id=1, uername='张三'}
main------User{id=2, uername='李四'}
main------User{id=2, uername='李四'}

 注意到线程名称每次打印出来的都是main,这很疑惑,我明明在线程的run()方法里打印的当前线程名称怎么都是main呢?之后我修改代码为如下

public class App {

    public static void main(String[] args)throws Exception {
        User user1 = new User(1, "张三");
        User user2 = new User(2, "李四");
        User user3 = new User(3, "王五");
        UserHolder.set(user3);
        MyThread t1 = new MyThread(user1);
        MyThread t2 = new MyThread(user2);
//        t1.run();
//        t2.run();
        Thread thread1 = new Thread(t1);
        Thread thread2 = new Thread(t2);
        thread1.start();
        thread2.start();
        System.out.println(Thread.currentThread().getName() + "------" + UserHolder.get());
    }

}

 此时运行结果为下面这样

main------User{id=3, uername='王五'}
Thread-0------null
Thread-0------User{id=1, uername='张三'}
Thread-1------null
Thread-1------User{id=2, uername='李四'}

 这下总是我想想的样子了,但是这是什么原因呢?很容易发现这两个方法是存在区别的,自己看不出来就去搜索了下,网上说的千篇一律就是这样子的。

1.用 start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2.run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

到此心中的疑惑得到了解答,满足了自己的好奇心,对于ThreadLocal也有了一定的认识。学到的新东西很满足。哈哈哈哈

猜你喜欢

转载自cccai-1234.iteye.com/blog/2308008