8种创建Java线程的方式,你知道几个?( 二 )


@RunWith(SpringRunner.class)@SpringBootTest(classes = Application.class)public class CreatingThread08Test { @Autowired private CreatingThread08Service creatingThread08Service; @Test public void test() { creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); }}运行结果如下:
task-3 is runningtask-2 is runningtask-1 is runningtask-4 is running可以看到每次执行方法时使用的线程都不一样 。
使用Spring异步方法的方式 , 可以说是相当地方便 , 适用于前后逻辑不相关联的适合用异步调用的一些方法 , 比如发送短信的功能 。
总结(1)继承Thread类并重写run()方法;
(2)实现Runnable接口;
(3)匿名内部类;
(4)实现Callabe接口;
(5)定时器(java.util.Timer);
(6)线程池;
(7)并行计算(Java8+);
(8)Spring异步方法;
 
福利上面介绍了那么多创建线程的方式 , 其实本质上就两种 , 一种是继承Thread类并重写其run()方法 , 一种是实现Runnable接口的run()方法 , 那么它们之间到底有什么联系呢?
请看下面的例子 , 同时继承Thread并实现Runnable接口 , 应该输出什么呢?
public class CreatingThread09 { public static void main(String[] args) { new Thread(()-> { System.out.println("Runnable: " + Thread.currentThread().getName()); }) { @Override public void run() { System.out.println("Thread: " + getName()); } }.start(); }}说到这里 , 我们有必要看一下Thread类的源码:
public class Thread implements Runnable { // Thread维护了一个Runnable的实例 private Runnable target; public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { // ... // 构造方法传进来的Runnable会赋值给target this.target = target; // ... } @Override public void run() { // Thread默认的run()方法 , 如果target不为空 , 会执行target的run()方法 if (target != null) { target.run(); } }}看到这里是不是豁然开朗呢?既然上面的例子同时继承Thread并实现了Runnable接口 , 根据源码 , 实际上相当于重写了Thread的run()方法 , 在Thread的run()方法时实际上跟target都没有关系了 。
所以 , 上面的例子输出结果为 Thread:Thread-0 , 只输出重写Thread的run()方法中的内容 。
最后欢迎大家一起交流 , 喜欢文章记得关注我点赞转发哟 , 感谢支持!




推荐阅读