持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
Runnable与Callable使用
创建线程有两种方式,即Runnable和Callable,但是看到线程Thread类的源码中执行的是Runnable对象,因此Future接口就需要转换成Runnable对象才能使用,而这种转换操作可以在线程池中实现,或者可以直接用FutureTask类来实现转换。
售票线程实现代码如下:
public class Ticket implements Runnable {
private int ticketNum = 6;
public void sellTicket(){
synchronized (this){
if(ticketNum > 0){
System.out.println(Thread.currentThread().getName()+" 窗口卖出了第 "+ ticketNum-- +" 张票");
}else{
System.out.println("票已售罄!");
}
}
}
@Override
public void run() {
while(ticketNum > 0){
sellTicket();
}
}
}
抢票线程执行代码如下:
public class MyCallable implements Callable<String> {
private Boolean flag =false;
@Override
public String call() throws Exception {
synchronized (this){
if(!this.flag){
this.flag = true;
return Thread.currentThread().getName()+" 抢票成功!";
}else{
return Thread.currentThread().getName()+" 抢票失败!" ;
}
}
}
}
运行类代码如下:
public class RunnableAndCallableRun {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Ticket ticket = new Ticket();
Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
t1.start();
t2.start();
t3.start();
MyCallable myCallable = new MyCallable();
FutureTask<String> task1 = new FutureTask<>(myCallable);
FutureTask<String> task2 = new FutureTask<>(myCallable);
FutureTask<String> task3 = new FutureTask<>(myCallable);
Thread eleven = new Thread(task1, "eleven");
Thread gxin = new Thread(task2, "Gxin");
Thread blue = new Thread(task3, "blue");
eleven.start();
gxin.start();
blue.start();
System.out.println(task1.get());
System.out.println(task2.get());
System.out.println(task3.get());
}
}
运行结果如下:
Thread-0 窗口卖出了第 6 张票
Thread-1 窗口卖出了第 5 张票
Thread-1 窗口卖出了第 4 张票
Thread-1 窗口卖出了第 3 张票
Thread-1 窗口卖出了第 2 张票
Thread-1 窗口卖出了第 1 张票
票已售罄!
eleven 抢票失败!
Gxin 抢票成功!
blue 抢票失败!
Future接口使用
Future类异步获取计算后的返回结果,该类中提供了检查是否计算完成、等待计算完成、获取计算结果的方法,其中通过get()方法能够在计算完成时完成时获取计算结果。