【并发编程】-- 线程Runnable与Callable使用

61 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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()方法能够在计算完成时完成时获取计算结果。