精华内容
下载资源
问答
  • C#process判断线程是否执行完毕

    万次阅读 2011-09-25 17:24:38
    如下使用: Process proc = new Process(); proc.StartInfo.FileName = "cmd "; proc.Start(); proc.WaitForExit(); 或如下使用: Pro
     如下使用: 
    Process   proc   =   new   Process();
    proc.StartInfo.FileName   =   "cmd ";
    proc.Start();
    proc.WaitForExit();

    或如下使用:
    Process   proc   =   new   Process();
    proc.EnableRaisingEvents   =   true;
    proc.Exited   +=   new   EventHandler(proc_Exited);
    proc.StartInfo.FileName   =   "cmd ";
    proc.Start();
    }

    void   proc_Exited(object   sender,   EventArgs   e)
    {
    //code   here
    }
    展开全文
  • 判断线程是否执行完毕

    千次阅读 2017-12-07 10:59:23
    在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...

    在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的功能是往一个文件异步地写入内容,我需要在所有的子线程写入完毕后在文件末尾写“---END---”及关闭文件流等,这个时候我就需要某个标志位可以告诉我是否线程池中所有的子线程都已经执行完毕,我使用这种方式来判断。

    public class MySemaphore {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            final File stream = new File("c:\\temp\\stonefeng\\stream.txt");
            final OutputStream os = new FileOutputStream(stream);
            final OutputStreamWriter writer = new OutputStreamWriter(os);
            final Semaphore semaphore = new Semaphore(10);
            ExecutorService exec = Executors.newCachedThreadPool();
            
            final long start = System.currentTimeMillis();
            for (int i = 0; i < 10000000; i++) {
                final int num = i;
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            semaphore.acquire();
                            writer.write(String.valueOf(num)+"\n");
                            semaphore.release();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                exec.submit(task);
            }
            exec.shutdown();
            while(true){  
               if(exec.isTerminated()){  
                    writer.write("---END---\n");
                    writer.close();
                    System.out.println("所有的子线程都结束了!");  
                    break;  
                }  
                Thread.sleep(1000);    
            }
            final long end = System.currentTimeMillis();
            System.out.println((end-start)/1000);
        }
    }

    当调用ExecutorService.shutdown方法的时候,线程池不再接收任何新任务,但此时线程池并不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。在调用shutdown方法后我们可以在一个死循环里面用isTerminated方法判断是否线程池中的所有线程已经执行完毕,如果子线程都结束了,我们就可以做关闭流等后续操作了。

    判断线程池中的线程是否全部执行完毕的另外一种解决方案则是使用闭锁(CountDownLatch)来实现,CountDownLatch是一种灵活的闭锁实现,它可以使一个或多个线程等待一组事件发生。闭锁状态包括一个计数器,该计数器被初始化为一个正数,表示需要等待的事件数量。countDown方法递减计数器,表示有一个事件已经发生了,而await方法等待计数器达到零,即表示需要等待的事情都已经发生。可以使用闭锁来这样设计程序达到目的:

    public class CountDownLatchApproach {
        public static void main(String[] args) throws IOException, InterruptedException {
            final int nThreads = 10;
            final CountDownLatch endGate = new CountDownLatch(nThreads);
            final File stream = new File("c:\\temp\\stonefeng\\stream.txt");
            final OutputStream os = new FileOutputStream(stream);
            final OutputStreamWriter writer = new OutputStreamWriter(os);
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < nThreads; i++) {
                final int num = i;
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            writer.write(String.valueOf(num)+"\n");
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            endGate.countDown();
                        }
                    }
                };
                exec.submit(task);
            }
            endGate.await();
            writer.write("---END---\n");
            writer.close();
        }
    }

    这种解决方案虽然可以达到目的但是性能差到没朋友,我更倾向于使用第一种方案。

    现在我们有了更优雅的第三种方案,它的执行性能也不错。

    public class MySemaphore {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            final File stream = new File("c:\\temp\\stonefeng\\stream.txt");
            final OutputStream os = new FileOutputStream(stream);
            final OutputStreamWriter writer = new OutputStreamWriter(os);
            final Semaphore semaphore = new Semaphore(10);
            ExecutorService exec = Executors.newCachedThreadPool();
            
            final long start = System.currentTimeMillis();
            for (int i = 0; i < 10000000; i++) {
                final int num = i;
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            semaphore.acquire();
                            writer.write(String.valueOf(num)+"\n");
                            semaphore.release();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                exec.submit(task);
            }
            exec.shutdown();
            exec.awaitTermination(1, TimeUnit.HOURS);
            writer.write("---END---\n");
            writer.close();
            System.out.println("ËùÓеÄ×ÓÏ̶߳¼½áÊøÁË£¡");  
            final long end = System.currentTimeMillis();
            System.out.println((end-start)/1000);
        }
    }





    展开全文
  • 摘要: 当任务量较大时,我们需要开启线程执行任务,但是在... 判断线程是否全部执行完毕(CountDownLatch) CountDownLatch示例 1.线程池 开启线程的方法有很多: 1.spring管理的ThreadPoolTaskExecutor线程池 2...

    摘要:

    当任务量较大时,我们需要开启线程执行任务,但是在一些特定需求下,我们需要在全部任务执行后获取执行结束标识等信息,此时就需要判断任务分配的线程是否全部结束。

    目录:

    1. 四种线程池
    2. 判断线程是否全部执行完毕(CountDownLatch)
    3. CountDownLatch示例

    1.声明线程池的方法

    开启线程的方法有很多:

    1.spring管理的ThreadPoolTaskExecutor线程池

    2.Java通过Executors提供的四种线程

      这里主要推荐Executor提供的四种线程池,也是使用较多的线程池。

      我看到一篇介绍特别好的博文,在这里把链接放上:https://www.jianshu.com/p/cf2dd6c203a2

    2.CountDownLatch判断线程是否全部结束

    • CountDownLatch可以理解为是一个计数器;
    • 该计数器的总数量是需要主动声明的;
    • 每当某个线程完成时,可以调用该计数器的countDown()方法来将计数器中的任务数减一;
    • 当计数器中的数字为0时,即表示所有任务已完成;
    • 使用await()来阻塞主线程往下面执行,知道计数器为0
    • 计数器关键方法如下图:
      //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
      public void await() throws InterruptedException { 
      
      };   
      //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
      public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
      
      };  
      //将count值减1
      public void countDown() { 
      
      };  

    3.Spring示例

    创建一个处理任务的线程:

    import java.util.concurrent.CountDownLatch;
    
    public class TestRunnal implements Runnable {
    
        private final CountDownLatch countDownLatch;  //传入计数器
        private int i;
         
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		work();  //处理任务
    		countDownLatch.countDown();//任务处理完成后,调用方法,将计数器数量-1
    	}
    
        // 声明构造函数,在new该线程的时候,传入构造器 和 需要处理的i
    	public TestRunnal(CountDownLatch countDownLatch, int i) {
    		super();
    		this.countDownLatch= countDownLatch;
    		this.i = i;
    	}
    	
    	private void work(){
    		for(int a=0;a<3;a++){
    			System.out.println("a:"+a);
    			try {
    				Thread.sleep(500);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			
    		}
    	}
    	
    }
    

    创建分配任务类,并测试

    public class Test {
     
    
    	public static void main(String[] args) {
    
            // 声明计数器,并指定计数器的最大值
            CountDownLatch countDownLatch= new CountDownLatch(5);
    
            // 声明三个线程
    		ExecutorService executor = Executors.newFixedThreadPool(3);
            
    		for (int i = 0; i < TOTAL_TASKS; i++) {
                // 调用线程,通过构造器把计数器和任务传递给线程
    			executor.execute(new TestRunnal(countDownLatch, i));
    
    		}
    		try {
    			latch.await(); //线程阻塞,当latch中数量为0时,放行
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    		System.out.println("此时全部线程均执行结束:over");
    		executor.shutdown();  //关闭线程池
    
    	}
    }

    测试结果如下图:

    展开全文
  • 上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。 exe.shutdown();该方法在加入线程队列的线程执行完之前不会执行。 exe.is...

    本文转载:https://blog.csdn.net/truong/article/details/40227435

    public class Test {  
        public static void main(String args[]) throws InterruptedException {  
            ExecutorService exe = Executors.newFixedThreadPool(50);  
            for (int i = 1; i <= 5; i++) {  
                exe.execute(new SubThread(i));  
            }  
            exe.shutdown();  
            while (true) {  
                if (exe.isTerminated()) {  
                    System.out.println("结束了!");  
                    break;  
                }  
                Thread.sleep(200);  
            }  
        }  

    上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。
    exe.shutdown();该方法在加入线程队列的线程执行完之前不会执行。
    exe.isTerminated();当shutdown()或者shutdownNow()执行了之后才会执行,并返回true。
    在上面的代码中必须有exe.isTerminated()的判断,否则在投入5个线程到线程池后会直接打印:“结束了”。不能达到我们想要的效果。
    通过while(true)循环判断exe.isTerminated()的值,为了防止过多的判断浪费资源,可设置线程睡眠Thread.sleep(200);正是由于这个睡眠,所以当所有线程池中的线程都执行完后,有可能延迟200ms才执行"结束了"语句。这个参数越小延迟越小,结果越准确。
    下面是子线程,子线程只是简单的将数字i打印出来;


    public class SubThread extends Thread{  
        private final int i;  
        public SubThread(int i){  
            this.i = i;  
        }  
        @Override  
        public void run(){  
            System.out.println(i);  
        }  
    }  
    执行结果:
    [plain] view plaincopy
    run:  
    3  
    1  
    4  
    5  
    2  
    结束了!  
    成功构建 (总时间: 2 秒)  

    子线程执行顺序不能控制,所以输出的结果是乱序的。

    展开全文
  • 1.根据线程池中的总线程数目等于完成的线程数目package com.luna.thread; import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import ...
  • 判断线程是否全部执行完毕

    千次阅读 2017-02-13 20:30:59
    在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...
  • MyThread:=TMyThread.Create(False);如何判断线程MyThread已执行完毕?因为程序中有个事件必须等某线程完成后才执行说明中说可以用ReturnValue,但我感觉这个值一直是0,没有变化啊----------------------用MyThre
  • 在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...
  • 在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...
  • 判断线程池中所有线程是否执行完毕 根据线程池中的总线程数目等于完成的线程数目:pool.getTaskCount()和pool.getCompletedTaskCount() public interface Future<V>Future 表示异步计算的结果。它提供了检查...
  • 1、先来看看这个多线程编程多线程用于数据采集时,速度明显很快,下面是基本方法,把那个auto写成采集数据方法即可。 using System; using System.Collections.Generic; using System.Text; using System....
  • CountdownEvent handler = new CountdownEvent(100); for (int i = 0; i ; i++) { var j = i; ThreadPool.QueueUserWorkItem(_ => {
  • 我尝试使用C#的task对快速排序算法进行并行化,简单的思路是:确定枢值位置后将前后两段分别交给两个不同的task并发执行,如此递归,最终能得到正确的排序结果 ...有没有方法可以判断当前所有task是否全部执行完毕

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 126,502
精华内容 50,600
关键字:

判断线程是否执行完毕