java 线程 callable_Java高并发,创建线程的新方式Callable接口

我们已经知道创建线程的方式有1.继承thread类。2.实现Runnable接口

接下来讲创建线程的新方式Callable接口,首先对比一下Runnable接口和Callable接口的区别:

首先创建两个资源类:分别是实现了Runnable接口和实现了Callable接口:

//Runnable接口

class MyThreadRunnable implementsRunnable {

@Overridepublic voidrun() {

}

}//Callable

class MyThreadCallable implements Callable{

@Overridepublic Integer call() throwsException {

System.out.println("******come in here");return 1024;

}

}

我们可以看到Callable存在泛型,以及返回值,这是对原来的老技术的增强,因为存在了返回值,提高了线程的细粒度。

接着我们看看Runnable创建线程的方式:

//Runnable

MyThreadRunnable myThread1=newMyThreadRunnable();

Thread t1=new Thread(myThread1);

但是通过该方式我们利用Callable来创建线程,却报错了,这是为什么 呢?

7d35f265e6c04db576b233d5a6b704d2.png

原因:Thread并不存在Callable的构造器!

如何创建Callable线程

首先查看API,看Runable接口:

955d7f687936e0583c4e36b284150fd5.png

b1acac50fe3861301ef253113645727c.png

e6fe82ee9e21f0a5e754f1e42fdf4129.png

ac2598a9cd9dcf934253d6c14a964d84.png

过程如下:

43bfac623bf9049037260984692adf0d.png

我们可以看到的是,这个构造器需要的参数就是Callable接口的实现类。

所以,我们创建线程的方式如下:

public classCallableDemo {public static voidmain(String[] args) {//MyThreadCallable myThread = new MyThreadCallable();

FutureTask futureTask = new FutureTask(newMyThreadCallable());new Thread(futureTask, "A").start();

System.out.println(futureTask.get());//1024 通过get方法来获取返回值

}

}

get方法具有阻塞性

public classCallableDemo {public static void main(String[] args) throwsExecutionException, InterruptedException {//MyThreadCallable myThread = new MyThreadCallable();

FutureTask futureTask = new FutureTask(newMyThreadCallable());new Thread(futureTask, "A").start();

System.out.println(futureTask.get());//1024 通过get方式来获取返回值 该方法会阻塞!

System.out.println(Thread.currentThread().getName()+"***计算完成");

}

}//Callable

class MyThreadCallable implements Callable{

@Overridepublic Integer call() throwsException {

System.out.println("******come in here");

Thread.sleep(5000);return 1024;

}

}

3d51085e45f67ee0b3a7bb1639355dd8.png

然后调转依一下主线程与futureTask线程执行的顺序:

public classCallableDemo {public static void main(String[] args) throwsExecutionException, InterruptedException {//MyThreadCallable myThread = new MyThreadCallable();

FutureTask futureTask = new FutureTask(newMyThreadCallable());new Thread(futureTask, "A").start();

System.out.println(Thread.currentThread().getName()+"***计算完成");

System.out.println(futureTask.get());//1024 通过get方式来获取返回值 该方法会阻塞!

}

}//Callable

class MyThreadCallable implements Callable{

@Overridepublic Integer call() throwsException {

System.out.println("******come in here");

Thread.sleep(5000);return 1024;

}

}

c9ce57c34c05dc9bcc3b418c146693c4.png

往往futureTask里面的get方法会被阻塞, 所以一般情况下我们先让main线程执行完毕防止由于等待futureTask而耗时。

futureTask的单一性

新增一个线程B:

public classCallableDemo {public static void main(String[] args) throwsExecutionException, InterruptedException {//MyThreadCallable myThread = new MyThreadCallable();

FutureTask futureTask = new FutureTask(newMyThreadCallable());new Thread(futureTask, "A").start();new Thread(futureTask, "B").start();

System.out.println(Thread.currentThread().getName()+ "***计算完成");

System.out.println(futureTask.get());//1024 通过get方式来获取返回值 该方法会阻塞!

}

}//Callable

class MyThreadCallable implements Callable{

@Overridepublic Integer call() throwsException {

System.out.println("******come in here");

Thread.sleep(5000);return 1024;

}

}

19a5e43e12d0c181a35e154f1f4be9d1.png

只执行了一次,因为一个futureTask,不管几个线程调用,调用的都是同一个futureTask对象!而且Runnable接口就不一样了:

public classCallableDemo {public static void main(String[] args) throwsExecutionException, InterruptedException {

MyThreadRunnable t= newMyThreadRunnable();

Thread thread= newThread(t);newThread(thread).run();newThread(thread).run();

}

}//Runnable接口

class MyThreadRunnable implementsRunnable {

@Overridepublic voidrun() {

System.out.println("******come in here");

}

}

以上..

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值