今天在阅读公众号文章关于线程安全问题的时候,在自己手动编写代码验证的时候,自己实现的结果与公众号提供的样例不一致。细看了一下,原来是博主使用的 start;而我使用的是 run。两者都是多线程的运行方法,那么它们有什么不同呐?
1、多线程的实现方式
众所周知,多线程的实现方式有两种:
- 继承Thead 类
- 实现 Runnable 接口
1.1、继承Thread 类
public class TestThread extends Thread{
static int index;
@Override
public void run() {
for (int i = 0; i < 20; i ++)
System.out.println(Thread.currentThread().getId() + " 的 index 是 " + index ++ );
}
}
复制代码
1.1.1、 start()
public static void main(String[] args) {
TestThread thread = new TestThread();
TestThread thread1 = new TestThread();
thread1.start();
thread.start();
thread.start();
}
复制代码
运行结果如下:
在这里我们发现了报错,
从结果上看,我们启动了两个线程执行业务。其中在一个线程二次调用 start() 方法的时候报错了。这是为什么呐?
1.1.2、run()
public static void main(String[] args) {
TestThread thread = new TestThread();
TestThread thread1 = new TestThread();
thread.run();
thread1.run();
}
复制代码
运行结果如下:
从结果上,启动了1个线程,index 的值递增的。
接下来,看下Runnable 接口的情况。
1.2、 实现 Runnable 接口
public class TestRunnable implements Runnable{
static int index;
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
for (int i = 0; i < 20; i ++)
System.out.println(Thread.currentThread().getName() + " 的 index 是 " + index ++ );
}
}
复制代码
1.2.1、 start()
public static void main(String[] args) {
TestRunnable testRunnable = new TestRunnable();
Thread thread = new Thread(testRunnable);
Thread thread1 = new Thread(testRunnable);
thread1.start();
thread.start();
thread.start();
}
复制代码
1.2.2、 run()
public static void main(String[] args) {
TestRunnable thread = new TestRunnable();
TestRunnable thread1 = new TestRunnable();
thread.run();
thread1.run();
}
复制代码
实现结果与上面对应的 run() 方法一致。
1.3 总结
从上面的实验可以看出。继承 Thread 类实现多线程,可以直接调用run() 方法和 start() 方法;但是实现 Runnable 接口实现多线程,使用 start() 方法还是需要借助 Thread 类。 那么我们来看下 start 和 run 方法。
- start 方法 会重新启动一个线程,然后去调用这个线程的 run 方法执行逻辑,但是无法重复调用。
- run 方法 就是一个普通的方法,可以重复调用,不会重新启动一个新的线程。