• 在线程池使用Callable和Runnable的区别以及如何关闭线程


    一、区别总结:

    1. Callable定义的方法是call,而Runnable定义的方法是run。
    2. Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,这是核心区别。
    3. Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。

    二、返回值的区别

      他们的核心区别是Callable可以返回Feature的对象,这个对象可以了解线程的运行情况,设置可以关闭线程!

    三、Runnable代码事例

    package com.qunar.synchro;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Created by qiu.li on 2015/9/21.
     * 这是一个继承Runnable的例子
     */
    public class TestRunnable implements Runnable {
    
        public static void main(String[] args) {
    
            ExecutorService runnableService = Executors.newFixedThreadPool(3);
    
            Runnable r1 = new TestRunnable();
            runnableService.submit(r1);
            runnableService.submit(new TestRunnable());
            runnableService.submit(new TestRunnable());
            runnableService.submit(new TestRunnable());
            runnableService.shutdown();
            
            System.out.println("go on");
            System.out.println("end");
        }
    
        @Override
        public void run() {
            for(int i=0;i<5; i++) {
                System.out.println(Thread.currentThread().getName() + ";random:" + (int) (Math.random() * 10 * 1000));
                try {
                    Thread.sleep( (int) (Math.random() * 10 * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    他的输出也比较简单,

    pool-1-thread-2;random:9491
    go on
    end
    pool-1-thread-3;random:6983
    pool-1-thread-1;random:718
    pool-1-thread-2;random:4214.....
    
    Process finished with exit code 0

    四、Callable代码

    package com.qunar.synchro;
    
    import com.sun.org.apache.xalan.internal.utils.FeatureManager;
    
    import java.util.concurrent.*;
    
    /**
     * Created by qiu.li on 2015/9/21.
     */
    public class TestCallable implements Callable<Boolean> {
    
        int i;
    
        public static void main(String[] args) {
    
            ExecutorService runnableService = Executors.newFixedThreadPool(3);
    
            Future<Boolean> r1 =  runnableService.submit(new TestCallable(1));
            Future<Boolean> r2 =  runnableService.submit(new TestCallable(2));
            Future<Boolean> r3 =  runnableService.submit(new TestCallable(3));
            try {
                boolean b2 = r2.get(); //r2先跑
                boolean b3 = r3.get(); //r3先跑
                System.out.println(b2);
                System.out.println(b3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            r1.cancel(true);//r1是死循环,现在退出
            runnableService.shutdownNow();
        }
    
        public TestCallable(int i){
            this.i = i;
        }
    
        @Override
        public Boolean call() {
            try {
                switch (i){
                    case 1:
                        while(true) {
                            System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //第一个线程
                            Thread.sleep(200);
                        }
                    default:
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //其他线程
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        }
    }

    运行的结果:

    pool-1-thread-1;i:1
    pool-1-thread-1;i:1
    pool-1-thread-1;i:1
    java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at com.qunar.synchro.TestCallable.call(TestCallable.java:46)
        at com.qunar.synchro.TestCallable.call(TestCallable.java:10)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    pool-1-thread-2;i:2
    pool-1-thread-3;i:3
    true
    true
    
    Process finished with exit code 0

    大家可以看见抛出的异常,这是因为在线程1被阻塞的时候(比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时),由于没有占用CPU,是不能给自己的中断状态置位的,这就会产生一个InterruptedException异常。

  • 相关阅读:
    CXF 与Spring整合配置
    CloudStack采用spring加载bean(cloud-framework-spring-module模块)
    CloudStack服务引擎配置(cloud-engine-service模块)
    Oracle用户、权限、角色管理
    合并日常使用指南
    oracle表空间建立与用户创建删除
    oracle 创建同义词
    Eclipse下svn的创建分支/合并/切换使用
    字符串转数字 简单代码实现
    Linux下调试段错误 (gdb,core,ulimit)
  • 原文地址:https://www.cnblogs.com/liqiu/p/4827512.html
Copyright © 2020-2023  润新知