java task和thread_java多线程学习(1) java线程Runnable,Thread,Callable,FutureTask

线程创建的方式

1.Thread对象

1.1 继承Thread对象

@Slf4j

public class MyThread extends Thread{

@Override

public void run() {

// 线程要执行的内容

log.debug("继承Thread方式");

}

}

public class Test1 {

public static void main(String[] args) {

new MyThread().start(); // 启动线程

}

}

1.2 直接使用Thread对象

public class Test1 {

public static void main(String[] args) {

Thread t = new Thread(){

@Override

public void run() {

log.debug("线程执行");

}

};

t.start();

}

}

2.Runnable接口

public class MyThread implements Runnable{

@Override

public void run() {

// 该线程执行内容

System.out.println("线程执行");

}

}

public static void main(String[] args) {

MyThread myThread = new MyThread();

Thread t1 = new Thread(myThread, "t1");

t1.start();

// jdk8 Lambda

Thread t2 = new Thread(()->{ System.out.println("t2执行");}, "t1");

t2.start();

Runnable runnable = ()->{ System.out.println("t3执行"); };

Thread t3 = new Thread(runnable, "t3");

t3.start();

}

3.Runnable和Thread的关系

Runnable的运行需要传入Thread中执行

Runnable runnable = ()->{ System.out.println("t3执行"); };

Thread t3 = new Thread(runnable, "t3");

t3.start();

点开Thread源码发现会把Runnable传个init方法

afa20a6dd5866004810810895140b7db.png

发现init又传给另外一个init

d13a25355d5ed2a038ea4f27389dcaf3.png

该init方法中发现他又传给了自身的一个变量

d5da78514f9c62b5a0f8253b4969da58.png

发现在Thread类中的run()方法最终调用了这个Runnable的run方法

497274c24ba5030daf318009a7c572e4.png

Runnable的run最终还是走的Thread的run,如果不重新run方法的情况下Thread的run方法会优先判断是否有Runnable传入,如果有那么就执行Runnable的run方法

3.Callable和FutureTask

FutureTask本身实现RunnableFuture

public class FutureTask implements RunnableFuture

RunnableFuture 又多继承了Runnable和Future

public interface RunnableFuture extends Runnable, Future

也就是说FutureTask也可以看做一个Runnable但是又强于Runnable

因为还继承了Future中的方法赋予了它获取线程运行结果的能力

14daa7e7eb06620cd19d79fc0d80a3e8.png

Callable只是一个接口其call 和 Runnable的run方法性质差不多,都是线程要运行其中的代码,但call有返回值的泛型同时也能做异常的抛出,run方法就不具备异常也得内部自己消化

31529ab3e11f1e4664efd4ecf3914c25.png

但我们运行代码的时候还是用的 start方法其还是去跑run方法,但发现我们这里并没有重写run方法而是一个call方法

63ac7d47b9666c0e3b3230f0a8c7267c.png

点开FutureTask 类,发现其内部重写了run方法,当我们在start启动线程的时候该run方法会去调用其传入的Callable的call方法,并在这里做了异常的处理并在这个时候把值返回给FutureTask的set方法供get等方法的调用

ec7ade81c1a0a38715f763994466d4f4.png

值返回给变量outcome

78a0192d0b3085a92eee98b260d2efe3.png

调用get方法的时候调用其report方法

65c370300bac755d32672cf6e003e51c.png

该方法的返回就是run方法调用call的值

2029a5abd7090decfbb85808ee6ee728.png

注意

437911220c113728abb521949ce216e4.png

看到get方法有返回值,也就是说他会一直阻塞到线程异步的返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值