今天在研究学习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也有了一定的认识。学到的新东西很满足。哈哈哈哈
相关推荐
在Java多线程编程中,`Thread` 类的 `run()` 方法和 `start()` 方法扮演着不同的角色,它们之间的区别是理解并发执行的关键。 首先,`start()` 方法是真正启动新线程的方法。当你调用 `Thread` 对象的 `start()` ...
* 此时只会会执行Run()方法,但是不会开启新的线程 */ //Handler h = new Handler(); //h.post(r); /* * 在java中真正开启线程的方法是这样的。 */ Thread t = new Thread(r); t.start(); ...
在Java编程语言中,理解和掌握线程的使用是至关重要的,特别是`Thread.start()`和`Thread.run()`这两个方法。它们在多线程编程中扮演着关键角色,但有着明显的区别。 首先,`Thread.start()`方法的主要作用是启动一...
`Thread`类是Java中用于创建和管理线程的核心类,而`start()`和`run()`方法是与线程执行密切相关的方法,它们之间存在显著的区别。 首先,`run()`方法是`Runnable`接口或`Thread`类中的一个成员方法。当你需要创建...
start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。...run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
在Java多线程编程中,理解`Thread`类的`start()`和`run()`方法的区别至关重要。这两个方法在实现线程并发执行时起到不同的作用。 首先,`start()`方法是用于启动一个新的线程。当你调用`start()`方法时,Java虚拟机...
本文将深入探讨`start()` 和 `run()` 方法的区别及其在多线程环境中的作用。 1. **start() 方法** `start()` 方法是启动线程的关键。当你调用 `Thread` 对象的 `start()` 方法时,Java虚拟机(JVM)会执行以下几...
通过理解`start()`和`run()`的方法以及如何正确地使用它们,可以有效地利用多线程提高程序的性能和响应性。同时,还需要注意到线程的生命周期管理,特别是如何安全地结束线程,以避免资源泄露或其他潜在的问题。
理解和掌握如何正确使用`start`方法和`run`方法对于编写高效的多线程程序至关重要。本文将深入探讨这两个方法的区别,帮助初学者更好地理解Java线程的工作原理。 首先,我们要明确`start`方法和`run`方法在Java线程...
Java线程中的`run()`和`start()`方法是线程编程中的关键概念,它们之间有着显著的区别。首先,我们来看一下这两个方法的基本解释。 1. `start()`方法:`start()`是真正启动线程的关键,它使得线程进入就绪(可运行...
第一点,start()方法和run()方法的区别。在Java中,start()方法是用于启动线程的方法,而run()方法是线程的主体,即真正的逻辑所在。start()方法调用run()方法,使线程进入就绪状态,使线程所代表的虚拟处理机处于可...
Java线程中start和run的区别详解 ...start和run方法之间的区别是非常重要的,start方法用于启动新线程,而run方法用于定义线程的执行体。在实际编程中,我们应该根据需要选择正确的方法,以达到多线程编程的目的。
在理解Thread类的start()和run()方法的区别时,我们需要深入探讨它们的工作原理。 首先,start()方法的主要作用是启动一个新的线程并执行该线程的run()方法。当调用start()时,Java虚拟机(JVM)会执行线程的初始化...
Thread 的 start 和 run 方法: start 方法用来启动线程,真正实现了多线程运行,这时无需等待 run 方法体代码执行完毕而直接继续执行下面的代码。通过调用 Thread 类的 start() 方法来启动一个线程,这时此线程...
面试中常见的问题在于理解`start()`方法与`run()`方法的区别。这里我们将详细探讨这两个方法以及它们在Java线程中的作用。 首先,`start()`方法是开启新线程的关键,而`run()`方法则是线程执行的具体任务。当你调用...
Java中启动线程start和run的两种方法 Java 中启动线程有两种方法,即继承 Thread 类和实现 Runnable 接口。由于 Java 无法实现多重继承,所以一般通过实现 Runnable 接口来创建线程。但是,无论哪种方法都可以通过 ...
接下来,我们来看`start`和`run`方法的区别。`start`方法是用于启动线程的关键,它是一个同步方法,确保线程不会在未准备好时启动。在`start`方法内部,它首先检查线程的状态,如果线程已经启动或已经终止,就会抛出...
在Python的多线程编程中,`run()`和`start()`是两个非常关键的方法,它们在处理线程执行方面有着显著的区别。理解这两个方法的工作原理对于编写高效的并发程序至关重要。 首先,`run()`方法并不是用来启动线程的,...
`start()`方法不会立即执行`run()`方法,而是将它放入线程的执行队列中,等待JVM调度执行。由于线程的并发性,两个线程可能会交错执行,因此输出结果可能会有不同顺序,但最终加法的结果总和应该为5050。 在多线程...
- `start()`方法会调用`run()`方法,并且使线程进入就绪状态。 4. **注意事项**: - 继承`Thread`类时只能继承一个父类,因此如果还需要继承其他类,则无法使用这种方式。 5. **优点**: - 可以直接访问`Thread...