文章插图
前言
并发是一件很美妙的事情,线程的调度与使用会让你除了业务代码外,有新的世界观,无论你是否参与但是这对于你未来的成长帮助很大 。
所以,让我们来好好看看在JAVA中启动线程的那几个方式与介绍 。
【Java线程的那几个启动方式】Thread
对于 Thread 我想这个基本上大家都认识的,在Java源码是这样说: java 虚拟机允许应用程序同时运行多个执行线程 。而这个的 Thread 就是程序的执行线程 。
如何使用它呢,其实在这个类中的源码已经给我们写好了,甚至是下面的 Runnable 的使用方式 。(如下是Thread源码)
/** * A <i>thread</i> is a thread of execution in a program. The Java * Virtual machine allows an Application to have multiple threads of * execution running concurrently. * <hr><blockquote><pre> * class PrimeThread extends Thread { * long minPrime; * PrimeThread(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime * . . . * } * } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <blockquote><pre> * PrimeThread p = new PrimeThread(143); * p.start(); * </pre></blockquote> * <p> * <hr><blockquote><pre> * class PrimeRun implements Runnable { * long minPrime; * PrimeRun(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime * . . . * } * } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <blockquote><pre> * PrimeRun p = new PrimeRun(143); * new Thread(p).start(); * </pre></blockquote> * <p> */public class Thread implements Runnable { //...}阅读源码的信息其实是最全的 ,我截取了部分的注释信息,起码我们现在可以无压力的使用这个两个方式来启动自己的线程 。
如果我们还要传递参数的话,那么我们设定一个自己的构造函数也是可以,如下方式:
public class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { System.out.println("一个子线程 BY " + getName()); }}这时读者应该发现,这个构造函数中的 name ,居然在 Thread 中也是有的,其实在Java中的线程都会自己的名称,如果我们不给其定义名称的话,java也会自己给其命名 。
/** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread} * {@code (null, null, name)}. * * @param name * the name of the new thread */public Thread(String name) { init(null, null, name, 0);}而我们最核心,也是大家最在意的应该就是如何启动并执行我们的线程了,是的,这个大家都知道的,就是这个 run 方法了 。
同时大家如果了解过了 Runnable ,我想大家都会知道这个 run 方法,其实是 Runnable 的方法,而我们本节的 Thread 也是实现了这个接口 。
这里,大家可能会好奇,不是应该是 start 这个方法吗?那么让我们看看 start 的源码 。
/** * Causes this thread to begin execution; the Java Virtual Machin * calls the <code>run</code> method of this thread. */public synchronized void start() { //...}通过 start 方法,我们可以了解到,就如同源码的启动模板中那样,官网希望,对于线程的启动,使用者是通过 start 的方式来启动线程,因为这个方法会让Java虚拟机会调用这个线程的 run 方法 。
其结果就是,一个线程去运行 start 方法,而另一个线程则取运行 run 方法 。同时对于这样线程,Java官方也说了,线程是不允许多次启动的,这是不合法的 。
所以如果我们执行下面的代码,就会报 java.lang.IllegalThreadStateException 异常 。
MyThread myThread = new MyThread("Thread");myThread.start();myThread.start();但是,如果是这样的代码呢?
MyThread myThread = new MyThread("Thread");myThread.run();myThread.run();myThread.start();//运行结果一个子线程 BY Thread一个子线程 BY Thread一个子线程 BY Thread这是不合理的,如果大家有兴趣,可以去试试并动手测试下,最好开调试模式 。
下面我们再看看,连 Thread 都要实现,且核心的 run 方法出处的 Runnable。
Runnable
比起 Thread 我希望大家跟多的使用 Runnable 这个接口实现的方式,对于好坏对比会在总结篇说下 。
推荐阅读
- 地球是迄今为止唯一适合人类生存的星球,研究极端 霍金说人类可以穿越到未来
- Redis的链表结构
- MySQL使用WHERE子句来过滤结果集中的行记录
- 分布式系统中"身份证"是如何生成的?
- 种任性的生活方式 茶器收藏
- Java8之Consumer、Supplier、Predicate和Function攻略
- 细数颜色釉瓷器的美 天然的美
- 若冰类玉的越瓷茶碗
- 五种材质让你了解中国茶具文化
- 建盏和天目的区别 你知道吗