Java并发编程核心方法与框架-Future和Callable的使用

Callable接口与Runnable接口对比的主要优点是Callable接口可以通过Future获取返回值。但是Future接口调用get()方法取得结果时是阻塞的,如果调用Future对象的get()方法时任务尚未执行完,则调用get()方法时一直阻塞到此任务完成。如果前面的任务耗时很多,则后面的任务调用get()方法就呈阻塞状态,大大影响运行效率。主线程不能保证首先获得的是最先完成任务的返回值,这是Future的缺点。

public class MyCallable implements Callable<String> {
    private int age;
    
    public MyCallable(int age) {
        super();
        this.age = age;
    }
    @Override
    public String call() throws Exception {
        TimeUnit.SECONDS.sleep(8);
        return "返回值 年龄是:" + age;
    }
    
    public static void main(String[] args) {
        MyCallable myCallable = new MyCallable(22);
        int corePoolSize = 2;
        int maximumPoolSize = 3;
        int keepAliveTime = 5;
        TimeUnit unit = TimeUnit.SECONDS;
        LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        Future<String> future = threadPoolExecutor.submit(myCallable);
        try {
            System.out.println(System.currentTimeMillis());
            String string = future.get();
            System.out.println(string);
            System.out.println(System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印结果如下:

1470904027660
返回值 年龄是:22
1470904035663

从打印结果看,可见get()方法具有阻塞的特性。

方法submit()不仅可以传入Callable对象,还可以传入Runnable对象,submit()方法支持有返回值和无返回值。

public class Run {
    public static void main(String[] args) {
        try {
            Runnable runnable = new Runnable() {
                
                @Override
                public void run() {
                    System.out.println("打印的信息");
                }
            };
            ExecutorService executorService = Executors.newCachedThreadPool();
            Future future = executorService.submit(runnable);
            System.out.println(future.get() + " " + future.isDone());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印结果如下:

打印的信息
null true

方法isDone()无阻塞特性。


使用ExecutorService接口中的方法submit(Runnable, T result)
public class User {
    private String username;
    private String password;
    //省略getter setter
}

public class MyRunnable implements Runnable {
    private User user;
    public MyRunnable(User user) {
        super();
        this.user = user;
    }
    @Override
    public void run() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        user.setUsername("admin");
        user.setPassword("123456");
    }
}

public class Main {
    FutureTask task;
    public static void main(String[] args) {
        try {
            User user = new User();
            MyRunnable myRunnable = new MyRunnable(user);
            int corePoolSize = 10;
            int maximumPoolSize = 10;
            int keepAliveTime = 10;
            TimeUnit unit = TimeUnit.SECONDS;
            LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>();
            ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
            Future<User> future = executor.submit(myRunnable, user);
            System.out.println(System.currentTimeMillis());
            System.out.println(user.getUsername() + "-" + user.getPassword());
            user = future.get();
            System.out.println(user.getUsername() + "-" + user.getPassword());
            System.out.println(System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

控制台打印结果如下:

1470908214853
null-null
admin-123456
1470908216855

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值