精华内容
下载资源
问答
  • 主要介绍了Java判断线程池线程是否执行完毕,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Android—判断线程池是否执行结束

    千次阅读 2015-09-01 11:18:15
    ExecutorService exe = Executors.newFixedThreadPool(30);  /* lowerorgdatalist.clear();  if(lowerorglist.size()>0){  for (int i = 0; i   m = lowerorglist.get(i);  exe.e
                   ExecutorService exe = Executors.newFixedThreadPool(30); 
    
    /*    lowerorgdatalist.clear();
       if(lowerorglist.size()>0){
        for (int i = 0; i < lowerorglist.size(); i++) { 
            m = lowerorglist.get(i);
               exe.execute(new mThread());  
        }
       }else{
           m = orglist.get(0);
           exe.execute(new mThread());  
       }
           exe.shutdown();  
           while (true) {  
               if (exe.isTerminated()) {  
                initCardView();
    System.out.println("结束了!");  
                   break;  
               }  
           

           } 




    原文地址:http://blog.csdn.net/truong/article/details/40227435

    展开全文
  • 判断线程池任务执行完成

    千次阅读 2018-10-19 15:08:52
    线程池执行任务,有时候,我们需要知道它是什么时候完成的。 1、.shutdown()、.isTerminated()进行判断 下面方法的解释: 当调用ExecutorService.shutdown方法的时候,线程池不再接收任何新任务,但此时线程池并不会...

    前言

    线程池执行任务,有时候,我们需要知道它是什么时候完成的。

    1、.shutdown()、.isTerminated()进行判断

    下面方法的解释:

    当调用ExecutorService.shutdown方法的时候,线程池不再接收任何新任务,但此时线程池并不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。解释退出了,如果在给新任务就会报错,一般不使用这种方法,建议使用第二种,这样线程池还可以用。


    
    		for(Long key:map.keySet()){
    		    final List<Long> idsThread = ids ;
    		    threadPoolUtils.execute(()->{
    		        List<Long> idParams = idsThread.subList(key.intValue()-1, map.get(key).intValue());
    		        final  List<CouponItemGood>  couponItemGoodFinal = couponItemGoodMapper.dataCpuponItemGoodfindByParamsIds(idParams);
    		        if (listKeyMonitor(couponItemGoodFinal, true,couponCheckVailds,mode)){
    		            return;
    		        }
    		    });
    		}
    
    
    			threadPoolUtils.getThreadPoolExecutor().shutdown();
            while(true){  
               if(threadPoolUtils.getThreadPoolExecutor().isTerminated()){  
                    System.out.println("所有的子线程都结束了!");  
                    break;  
                }  
                Thread.sleep(10000);    //防止while判断过快,浪费资源,这里我设置为10秒大家看情况设置
            }
    
    

    1.2、shutdown()、shutdownNow()、awaitTerminate(long timeout,TimeUnit unit)区别

    1、shutdown()

    问:shutdown()有什么功能?

    答:阻止新来的任务提交,对已经提交了的任务不会产生任何影响。当已经提交的任务执行完后,它会将那些闲置的线程(idleWorks)进行中断,这个过程是异步的。

    问:如何阻止新来的任务提交?

    答:通过将线程池的状态改成SHUTDOWN,当再将执行execute提交任务时,如果测试到状态不为RUNNING,则抛出rejectedExecution,从而达到阻止新任务提交的目的。

    问:为何对提交的任务不产生任何影响?

    答:在调用中断任务的方法时,它会检测workers中的任务,如果worker对应的任务没有中断,并且是空闲线程,它才会去中断。 另外的话,workQueue中的值,还是按照一定的逻辑顺序不断的往works中进行输送的,这样一来,就可以保证提交的任务按照线程本身的逻辑执行,不受到影响。

    2、shutdownNow()

    问:shutdownNow()有什么功能?

    答:阻止新来的任务提交,同时会中断当前正在运行的线程,即workers中的线程。 另外它还将workQueue中的任务给移除,并将这些任务添加到列表中进行返回。

    问:如何阻止新来的任务提交?

    答:通过将线程池的状态改成STOP,当再将执行execute提交任务时,如果测试到状态不为RUNNING,则抛出rejectedExecution,从而达到阻止新任务提交的目的.

    问:如果我提交的任务代码块中,正在等待某个资源,而这个资源没到,但此时执行shutdownNow(),会出现什么情况?

    答:当执行shutdownNow()方法时,如遇已经激活的任务,并且处于阻塞状态时,shutdownNow()会执行1次中断阻塞的操作,此时对应的线程报InterruptedException,如果后续还要等待某个资源,则按正常逻辑等待某个资源的到达。例如,一个线程正在sleep状态中,此时执行shutdownNow(),它向该线程发起interrupt()请求,而sleep()方法遇到有interrupt()请求时,会抛出InterruptedException(),并继续往下执行。在这里要提醒注意的是,在激活的任务中,如果有多个sleep(),该方法只会中断第一个sleep(),而后面的仍然按照正常的执行逻辑进行。

    3、awaitTermination(long timeout,TimeUnit unit)

    简单来说,awaitTermination会一直等待,直到线程池状态为TERMINATED或者,等待的时间到达了指定的时间。

      exec.shutdown();
      exec.awaitTermination(1, TimeUnit.HOURS);
    
    

    2、使用执行任务数量进行判断


    for(Long key:map.keySet()){
        final List<Long> idsThread = ids ;
        threadPoolUtils.execute(()->{
            List<Long> idParams = idsThread.subList(key.intValue()-1, map.get(key).intValue());
            final  List<CouponItemGood>  couponItemGoodFinal = couponItemGoodMapper.dataCpuponItemGoodfindByParamsIds(idParams);
            if (listKeyMonitor(couponItemGoodFinal, true,couponCheckVailds,mode)){
                return;
            }
        });
    }
    
    //当线程池完成的线程数等于线程池中的总线程数
    boolean allThreadsIsDone = threadPoolUtils.getThreadPoolExecutor().getTaskCount() == threadPoolUtils.getThreadPoolExecutor().getCompletedTaskCount();
    log.info("\n"+allThreadsIsDone+"当前线程池完成状态:线程池工作任务数量"+threadPoolUtils.getThreadPoolExecutor().getTaskCount()+"线程池完成工作数量"+threadPoolUtils.getThreadPoolExecutor().getCompletedTaskCount());
    while (!allThreadsIsDone) {
        allThreadsIsDone = threadPoolUtils.getThreadPoolExecutor().getTaskCount() == threadPoolUtils.getThreadPoolExecutor().getCompletedTaskCount();
        if (allThreadsIsDone) {
            break;
        }
        try {
            log.info("\n"+allThreadsIsDone+"当前线程池完成状态:线程池工作任务数量"+threadPoolUtils.getThreadPoolExecutor().getTaskCount()+"线程池完成工作数量"+threadPoolUtils.getThreadPoolExecutor().getCompletedTaskCount());
            Thread.sleep(10000); //睡上10秒钟吧
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    

    ContactAuthor

    展开全文
  • 主要介绍了Java 判断线程池所有任务是否执行完毕的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 解决问题,实现判断线程池中的线程是否执行完成4-1.FutureTask4-2.实现代码(使用isDone)4-3.实现代码(使用get) 1.先写结果 使用FutureTask类即可实现判断线程池中的线程的状态,提供的方法是isDone(),get()。 ...

    1.先写结果

    使用FutureTask类即可实现判断线程池中的线程的状态,提供的方法是isDone(),get()。

        private volatile int state;
        private static final int NEW          = 0;
        private static final int COMPLETING   = 1;
        private static final int NORMAL       = 2;
        private static final int EXCEPTIONAL  = 3;
        private static final int CANCELLED    = 4;
        private static final int INTERRUPTING = 5;
        private static final int INTERRUPTED  = 6;
    

    2.判断某个线程是否执行完成(不使用线程池)

    在不适用线程池的情况下,一般使用Thread类提供的isAlive方法来判断线程的状态。当线程开始处于活动状态时,返回true,当线程未开始或者已结束等其他状态,返回false。

        public static void main(String[] args) {
            Thread thread = new Thread(() -> System.out.println("线程开始执行"));
            thread.start();
            System.out.println(thread.isAlive());
            //使用while循环判断线程是否执行完成
        }
    

    3.在线程池中不能使用isAlive判断线程状态的原因

    3-1.错误示例

        public static void main(String[] args) {
            Thread task = new Thread(() -> {
                System.out.println("线程1开始");
                try {
                    Thread.sleep(10000); //10s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            Thread task2 = new Thread(() -> {
                System.out.println("线程2开始");
                try {
                    Thread.sleep(20000); //20s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
            fixedThreadPool.execute(task);
            fixedThreadPool.execute(task2);
            fixedThreadPool.shutdown();
    		
    		//判断线程池是否执行完成
            while (!fixedThreadPool.isTerminated()) {
                System.out.println("还在执行...");
                if (task.isAlive()) { //理论上前10s这里应该是true,但是实际返回的是false
                    System.out.println("线程1执行完成");
                }
                if (task2.isAlive()) { //理论上前20s这里应该是true,但是实际返回的是false
                    System.out.println("线程2执行完成");
                }
                try {
                    Thread.sleep(2000); //2s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("主线程结束");
        }
    

    原因:isAlive方法是针对于类来说的,当前Thread类是否执行过start方法就决定了isAlive方法返回的是否是true。而在线程池中,真正创建线程并运行的是ThreadFactory工厂类。

    3-2.创建线程工厂

    下面是创建Thread的源码,可以看到只是调用我们传入Runnable的run方法而已。这个返回的才是真正的在线程池中运行的线程。

    public Thread newThread(final Runnable r) {
                if (group.isDestroyed()) {
                    group = new ThreadGroup(group.getParent(), name + "-workqueue");
                }
                Runnable wrapped = new Runnable() {
                    public void run() {
                        ++approxThreadCount;
                        try {
                            r.run();
                        } finally {
                            --approxThreadCount;
                        }
                    }
                };
                final Thread t = new Thread(group, 
                                      wrapped, 
                                      name + "-workqueue-" + threadNumber.getAndIncrement(),
                                      0);
                AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                    public Boolean run() {
                        t.setContextClassLoader(loader);
                        return true;
                    }
                });
                t.setDaemon(true);
                if (t.getPriority() != Thread.NORM_PRIORITY) {
                    t.setPriority(Thread.NORM_PRIORITY);
                }
                return t;
            }
    

    3-3.创建线程方法(ThreadPoolExecutor)

    ThreadPoolExecutor中创建线程(创建Worker时)。

    private boolean addWorker(Runnable firstTask, boolean core) {
    //firstTask就是我们一开始传入的类
            retry:
            for (;;) {
                int c = ctl.get();
                int rs = runStateOf(c);
    
                // Check if queue empty only if necessary.
                if (rs >= SHUTDOWN &&
                    ! (rs == SHUTDOWN &&
                       firstTask == null &&
                       ! workQueue.isEmpty()))
                    return false;
    
                for (;;) {
                    int wc = workerCountOf(c);
                    if (wc >= CAPACITY ||
                        wc >= (core ? corePoolSize : maximumPoolSize))
                        return false;
                    if (compareAndIncrementWorkerCount(c))
                        break retry;
                    c = ctl.get();  // Re-read ctl
                    if (runStateOf(c) != rs)
                        continue retry;
                    // else CAS failed due to workerCount change; retry inner loop
                }
            }
    
            boolean workerStarted = false;
            boolean workerAdded = false;
            Worker w = null;
            try {
                w = new Worker(firstTask); //调用了上面的创建工厂方法
                final Thread t = w.thread; //得到了一个新的Thread
                if (t != null) {
                    final ReentrantLock mainLock = this.mainLock;
                    mainLock.lock();
                    try {
                        // Recheck while holding lock.
                        // Back out on ThreadFactory failure or if
                        // shut down before lock acquired.
                        int rs = runStateOf(ctl.get());
    
                        if (rs < SHUTDOWN ||
                            (rs == SHUTDOWN && firstTask == null)) {
                            if (t.isAlive()) // precheck that t is startable
                                throw new IllegalThreadStateException();
                            workers.add(w);
                            int s = workers.size();
                            if (s > largestPoolSize)
                                largestPoolSize = s;
                            workerAdded = true;
                        }
                    } finally {
                        mainLock.unlock();
                    }
                    if (workerAdded) {
                        t.start(); //启动了Thread,所以说我们传入的Thread压根没有执行,只是执行了我们的run方法
                        workerStarted = true;
                    }
                }
            } finally {
                if (! workerStarted)
                    addWorkerFailed(w);
            }
            return workerStarted;
        }
    

    4.解决问题,实现判断线程池中的线程是否执行完成

    4-1.FutureTask

    使用idea的查看类继承结构(ctrl+alt+shift+U):
    继承结构

    4-2.实现代码(使用isDone)

    public static void main(String[] args) {
    
            FutureTask<Boolean> futureTask = new FutureTask<>(() -> {
                System.out.println("线程1开始");
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":线程1结束");
                return true;
            });
            FutureTask<Boolean> futureTask1 = new FutureTask<>(() -> {
                System.out.println("线程2开始");
                try {
                    Thread.sleep(20 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":线程2结束");
                return true;
            });
    
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
            fixedThreadPool.execute(futureTask);
            fixedThreadPool.execute(futureTask1);
            fixedThreadPool.shutdown();
    
            while (!fixedThreadPool.isTerminated()) {
                System.out.println("还在执行...");
                System.out.println("1:"+futureTask.isDone()); //前10s输出false,后10s输出true
                System.out.println("2:"+futureTask1.isDone()); //20s输出false
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("1:"+futureTask.isDone()); //true
            System.out.println("2:"+futureTask1.isDone()); //true
            System.out.println("主线程结束");
        }
    

    使用isDone()来判断线程是否结束,不是NEW状态就返回true,包括线程已经取消或者异常

        public boolean isDone() {
            return state != NEW;
        }
    

    4-3.实现代码(使用get)

    还可以通过get()方法来获取返回值,因为FutureTask是有返回值的,在线程执行完成之前,get()方法会一直处于堵塞状态。这样就可以在某个线程执行完成后再执行其他相关的代码。

        public static void main(String[] args) {
    
            FutureTask<Boolean> futureTask = new FutureTask<>(() -> {
                System.out.println("线程1开始");
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":线程1结束");
                return true;
            });
            FutureTask<Boolean> futureTask1 = new FutureTask<>(() -> {
                System.out.println("线程2开始");
                try {
                    Thread.sleep(20 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":线程2结束");
                return true;
            });
    
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
            fixedThreadPool.execute(futureTask);
            fixedThreadPool.execute(futureTask1);
            fixedThreadPool.shutdown();
    
            try {
                Boolean isSuccess = futureTask.get(); //10s后返回结果
                System.out.println("获取到线程1执行结果:" + isSuccess);
                Boolean isSuccess1 = futureTask1.get(); //20s后返回结果
                System.out.println("获取到线程2执行结果:" + isSuccess1);
                if (isSuccess && isSuccess1) {
                    System.out.println("线程执行完毕");
                }
            } catch (InterruptedException | ExecutionException e) {
                System.out.println("线程异常");
            }
            System.out.println("主线程结束");
        }
    

    使用get()来获取线程的返回值,当获取到线程的返回值时,说明线程已经执行完毕。get()方法的重载方法get(long timeout, TimeUnit unit)方法,可以设置最长堵塞时间,以免堵塞时间过长出现其他问题。

        public V get() throws InterruptedException, ExecutionException {
            int s = state;
            if (s <= COMPLETING)
                s = awaitDone(false, 0L);
            return report(s);
        }
    
    展开全文
  • 判断线程池中的线程是否全部执行完毕 在使用多线程中我们会使用 java.util.concurrent.Executors的线程池,当多个子线程异步执行的时候,调用ExecutorService.shutdown方法,线程池不再接收任何新的任务,但此时...

    判断线程池中的线程是否全部执行完毕

    在使用多线程中我们会使用 java.util.concurrent.Executors的线程池,当多个子线程异步执行的时候,调用ExecutorService.shutdown方法,线程池不再接收任何新的任务,但此时线程池并不会立刻退出,直到添加到线程池中的任务都已经执行处理完成,才会退出,我们如何判断线程池中所有的子线程都已经执行完毕,然后继续执行后续操作。

    方式一

    调用ExecutorService 中的isTerminated方法。
    在调用shutdown方法后我们可以在一个死循环里面用isTerminated方法判断是否线程池中的所有线程已经执行完毕
    在这里插入图片描述

    方式二

    调用ExecutorService 中的awaitTermination()方法,等待子线程结束

    在这里插入图片描述

    方式三

    闭锁CountDownLatch
    闭锁状态包括一个计数器,该计数器被初始化为一个正数,表示需要等待的事件数量,递减计数,而await方法等待计数器达到零,即表示线程结束
    在这里插入图片描述

    展开全文
  • 判断线程池是否有任务正在执行

    千次阅读 2019-11-23 18:43:40
    在使用线程池提交异步任务时,当需要做多用户互斥操作时,用户A在操作关键数据时,用户B也在操作,系统检测到A下发的数据任务还在执行则禁止用户B的下发的任务,可以通过判断线程池是否存在正在执行的任务来操作,...
  • Java 判断线程池 执行完毕

    千次阅读 2014-04-14 20:10:36
    工作中,遇到很多情况需要使用线程,或者线程池。但往往我们需要dengda
  • 在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...
  • 1.判断线程池中所有线程是否执行完毕根据线程池中的总线程数目等于完成的线程数目package com.luna.thread;import java.util.Random;import java.util.concurrent.LinkedBlockingQueue;import java.util.con...
  • Java如何判断线程池所有任务是否执行完毕 2014-10-18 23:10 16842人阅读 评论(0) 收藏 举报 [java] view plaincopy package csdn;   import java.util.concurrent.ExecutorService; import ...
  • 我就废话不多说了,大家还是直接看代码吧~上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。exe.shutdown();该方法在加入线程队列的...
  • 判断线程池所有任务是否执行完毕

    千次阅读 2017-02-28 14:19:30
    创建一个固定大小的线程池。 shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭。 awaitTermination():用于等待子线程结束,再继续执行下面的代码。该例中我设置一直等着子线程结束。 public ...
  • 但在执行的过程中遇到问题是:子线程还未执行完,主线程就结束了导致。 (为什么会这样呢?是什么原因造成的呢?按理来说主线程应等待子线程结束后再结束滴吖!! 我在简单的实例中不会存在这个问题的,但放到项.....
  • 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。   抛出: SecurityException - 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的...
  • 这些都需要我们判断线程池的任务是否都已经完成。 判断线程池中的任务是否全部完成,方式有不少,这里我来整理一下。 一、使用线程池的原生函数isTerminated(); 优点:操作简便; 缺点:需要主线程阻塞; execu...
  • 在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...
  • 正是由于这个睡眠,所以当所有线程池中的线程都执行完后,有可能延迟200ms才执行"结束了"语句。这个参数越小延迟越小,结果越准确。 下面是子线程,子线程只是简单的将数字i打印出来; public class SubThread ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 99,886
精华内容 39,954
关键字:

判断线程池是否执行完