精华内容
下载资源
问答
  • 在使用多线程的时候有时候我们会使用 java.util.concurrent.Executors的线程池,当多个线程异步执行的时候,我们往往不好判断是否线程池中所有的子线程都已经执行完毕,但有时候这种判断却很有用,例如我有个方法的...

    在使用多线程执行任务的时候,在某些场景下需要判断线程池中所有线程是否都已执行完毕,例如:我有个方法的功能是往一个文件异步地写入内容,我需要在所有的子线程写入完毕后在文件末尾写“---END---”及关闭文件流等,这个时候我就需要某个标志位可以告诉我是否线程池中所有的子线程都已经执行完毕。下面我总结了两种方式来判断。

    第一种方式:使用Semaphore

    Semaphore简介:

    Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类。

    所谓Semaphore即 信号量 的意思。

    这个叫法并不能很好地表示它的作用,更形象的说法应该是许可证管理器。

    其作用在JDK注释中是这样描述的:

    A counting semaphore. 
    Conceptually, a semaphore maintains a set of permits. 
    Each {@link #acquire} blocks if necessary until a permit is available, and then takes it. 
    Each {@link #release} adds a permit, potentially releasing a blocking acquirer. 
    However, no actual permit objects are used; the {@code Semaphore} just keeps a count of the number available and acts accordingly.

    翻译过来,就是:

    Semaphore是一个计数信号量。
    从概念上将,Semaphore包含一组许可证。
    如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证。
    每个release()方法都会释放持有许可证的线程,并且归还Semaphore一个可用的许可证。
    然而,实际上并没有真实的许可证对象供线程使用,Semaphore只是对可用的数量进行管理维护。
    了解更多Semaphore可以参考以下博客:

    https://blog.csdn.net/hanchao5272/article/details/79780045

    具体使用:

    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);
        }
    }
    

     

    第二种方式:CountDownLatch

    判断线程池中的线程是否全部执行完毕的另外一种解决方案则是使用闭锁(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();
        }
    }
    

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

     

     

     

     

     

     

    展开全文
  • 所以采用多线程抽取方式,其中 每五分钟抽一次。 创建五个线程A,B,C,D,E 其中线程A 执行的表:table 数据量特别大,导致五分钟没有抽取完毕,第二次又开始抽取了table,遇到之前线程没有抽取完的表需要跳过,本次不...
  • 在使用多线程中我们会使用 java.util.concurrent.Executors的线程池,当多个子线程异步执行的时候,调用ExecutorService.shutdown方法,线程池不再接收任何新的任务,但此时线程池并不会立刻退出,直到添加到线程池中...

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

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

    方式一

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

    方式二

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

    在这里插入图片描述

    方式三

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

    展开全文
  • 我尝试使用C#的task对快速排序算法进行并行化,简单的思路是:确定枢值位置后将前后两段分别交给两个不同的task并发执行,如此递归,最终能得到正确的排序结果 ...有没有方法可以判断当前所有task是否全部执行完毕
  • 高手有什么办法没,如何判断15个线程是否结束。 就是如何<span style="color: red"><span style="font-size: medium">让主线程等待所有子线程执行完毕</span></span> <pre name="code" ...
  • 其实这类问题的核心论点都是:如何在一个线程中得知其他线程是否执行完毕。 假设现在有 3 个线程在运行,需要在主线程中得知他们的运行结果;可以分为以下几步: 定义一个计数器为 3。 每个线程完成任务后计数减...

    前几天被问到,多个线程同时查询一张表,最后汇总查询结果返回,那么就存在一个问题,如何判断多个线程是否全部已经处理完成。

    网上整理资料,总体有两种方法:

    第一种:自己实现,即自己实现计数器,具体操作为:

    其实这类问题的核心论点都是:如何在一个线程中得知其他线程是否执行完毕。

    假设现在有 3 个线程在运行,需要在主线程中得知他们的运行结果;可以分为以下几步:

    • 定义一个计数器为 3。
    • 每个线程完成任务后计数减一。
    • 一旦计数器减为 0 则通知等待的线程。

    所以也很容易想到可以利用等待通知机制来实现,阻塞队列的类似。

    按照这个思路自定义了一个 MultipleThreadCountDownKit 工具,构造函数如下:

    考虑到并发的前提,这个计数器自然需要保证线程安全,所以采用了 AtomicInteger

    所以在初始化时需要根据线程数量来构建对象。

    计数器减一

    当其中一个业务线程完成后需要将这个计数器减一,直到减为0为止。

        /**     * 线程完成后计数 -1     */    
        public void countDown(){
            if (counter.get() <= 0){ 
                       return;     
             }
            int count = this.counter.decrementAndGet();
            if (count < 0){
                        throw new RuntimeException("concurrent error") ;
             }
            if (count == 0){ 
                       synchronized (notify){
                                       notify.notify();  
                       }    
            }
        }
    

    利用 counter.decrementAndGet() 来保证多线程的原子性,当减为 0 时则利用等待通知机制来 notify 其他线程。

    等待所有线程完成

    而需要知道业务线程执行完毕的其他线程则需要在未完成之前一直处于等待状态,直到上文提到的在计数器变为 0 时得到通知。

        /**     * 等待所有的线程完成     * @throws InterruptedException     */        
        public void await() throws InterruptedException {
            synchronized (notify) {
                while (counter.get() > 0) {
                    notify.wait();
                }
                if (notifyListen != null) {
                    notifyListen.notifyListen();
                }
            }
        }
    

    原理也很简单,一旦计数器还存在时则会利用 notify 对象进行等待,直到被业务线程唤醒。

    同时这里新增了一个通知接口可以自定义实现唤醒后的一些业务逻辑,后文会做演示。

    并发测试

    主要就是这两个函数,下面来做一个演示。

    • 初始化了三个计数器的并发工具 MultipleThreadCountDownKit
    • 创建了三个线程分别执行业务逻辑,完毕后执行 countDown()
    • 线程 3 休眠了 2s 用于模拟业务耗时。
    • 主线程执行 await() 等待他们三个线程执行完毕。

    通过执行结果可以看出主线程会等待最后一个线程完成后才会退出;从而达到了主线程等待其余线程的效果。

    MultipleThreadCountDownKit multipleThreadKit = new MultipleThreadCountDownKit(3); 
       multipleThreadKit.setNotify(() -> LOGGER.info("三个线程完成了任务"));

    也可以在初始化的时候指定一个回调接口,用于接收业务线程执行完毕后的通知。

    当然和在主线程中执行这段逻辑效果是一样的(和执行 await() 方法处于同一个线程)。

    第二种方法:CountDownLatch

    当然我们自己实现的代码没有经过大量生产环境的验证,所以主要的目的还是尝试窥探官方的实现原理。

    所以我们现在来看看 juc 下的 CountDownLatch 是如何实现的。

    通过构造函数会发现有一个 内部类 Sync,他是继承于 AbstractQueuedSynchronizer ;这是 Java 并发包中的基础框架,都可以单独拿来讲了,所以这次重点不是它,今后我们再着重介绍

    countDown

    其实他的核心逻辑和我们自己实现的区别不大。

        public void countDown() {
            sync.releaseShared(1);
        }
    
        public final boolean releaseShared(int arg) {
            if (tryReleaseShared(arg)) {
                doReleaseShared();
                return true;
            }
            return false;
        }
    

    利用这个内部类的 releaseShared 方法,我们可以理解为他想要将计数器减一。

    看到这里有没有似曾相识的感觉。

    没错,在 JDK1.7 中的 AtomicInteger 自减就是这样实现的(利用 CAS 保证了线程安全)。

    只是一旦计数器减为 0 时则会执行 doReleaseShared 唤醒其他的线程。

    这里我们只需要关心红框部分(其他的暂时不用关心,这里涉及到了 AQS 中的队列相关),最终会调用 LockSupport.unpark 来唤醒线程;就相当于上文调用 object.notify()

    所以其实本质上还是相同的。

    await

    其中的 await() 也是借用 Sync 对象的方法实现的。

    public void await() throws InterruptedException {
            sync.acquireSharedInterruptibly(1);
        }
    
        public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            //判断计数器是否还未完成            
            if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg);
        }
    
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }
    

    一旦还存在未完成的线程时,则会调用 doAcquireSharedInterruptibly 进入阻塞状态。

         private final boolean parkAndCheckInterrupt() {
            LockSupport.park(this);
            return Thread.interrupted();
        }
    

    同样的由于这也是 AQS 中的方法,我们只需要关心红框部分;其实最终就是调用了 LockSupport.park 方法,也就相当于执行了 object.wait() 。

    • 所有的业务线程执行完毕后会在计数器减为 0 时调用 LockSupport.unpark 来唤醒线程。
    • 等待线程一旦计数器 > 0 时则会利用 LockSupport.park 来等待唤醒。

    这样整个流程也就串起来了,它的使用方法也和上文的类似。

    就不做过多介绍了。

    实际案例

    同样的来看一个实际案例。

    在上一篇《一次分表踩坑实践的探讨》提到了对于全表扫描的情况下,需要利用多线程来提高查询效率。

    比如我们这里分为了 64 张表,计划利用 8 个线程来分别处理这些表的数据,伪代码如下:

        CountDownLatch count = new CountDownLatch(64);
        ConcurrentHashMap total = new ConcurrentHashMap();
        for(Integer i = 0;i<=63;i++){
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    List value = queryTable(i);
                    total.put(value, NULL);
                    count.countDown();
                }
            });
        }
        count.await();
        System.out.println("查询完毕");
    

    这样就可以实现所有数据都查询完毕后再做统一汇总;代码挺简单,也好理解(当然也可以使用线程池的 API)。

    总结

    CountDownLatch 算是 juc 中一个高频使用的工具,学会和理解他的使用会帮助我们更容易编写并发应用。

     

     

     

    展开全文
  • 多线程并发,我们往往采用线程池来管理并发的线程。但是,我们往往有这样的需要:要求在线程池中的任务都完成后才能执行后续的任务,或者需要任务都完成后释放资源或向数据库写入状态。这些都需要我们判断线程池的...

    前言:

    多线程并发,我们往往采用线程池来管理并发的线程。但是,我们往往有这样的需要:要求在线程池中的任务都完成后才能执行后续的任务,或者需要任务都完成后释放资源或向数据库写入状态。这些都需要我们判断线程池的任务是否都已经完成。
    判断线程池中的任务是否全部完成,方式有不少,这里我来整理一下。

    一、使用线程池的原生函数isTerminated();

    优点:操作简便;

    缺点:需要主线程阻塞;

    executor提供一个原生函数isTerminated()来判断线程池中的任务是否全部完成。全部完成返回true,否则返回false。

    栗子:

    package my.thread.test;
    
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    class AnyTask implements Runnable{
    	
    	public void run() {
    		try {
    			Thread.sleep(3000);
    			System.out.println("普通任务执行执行完毕!");
    				
    		}catch(Exception e) {
    			
    			e.printStackTrace();
    			
    		}
    	}
    }
    
    class EndTask {
    	public void taskRun() {
    		try {
    			System.out.println("开始执行最终任务");
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    			
    		}
    	}
    }
    
    
    public class TeminatedTest {
    	
    	public static void main(String[] args) {
    		try {
    			ExecutorService exector = Executors.newFixedThreadPool(7);
    		
    			for(int i =0;i<10;i++) {
    				AnyTask anyTask = new AnyTask();
    				exector.execute(anyTask);
    			}
    			exector.shutdown();
    		
    			while(true) {
    				if(exector.isTerminated()) {
    					
    					EndTask endTask = new EndTask();
    					endTask.taskRun();
    					
    					break;
    					
    				}else {
    					Thread.sleep(3000);
    				}
    			}
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
    		
    	}
    }
    
    

    操作很方便,但要求主线程阻塞,这样对接口化编程很不友好。

    二、使用CountDownLatch:

    优点:操作相对简便,可以把等待线程池中任务完成后的后续工作做成任务,同样放到线程池中运行,简单来说,就是可以控制线程池中任务执行的顺序。

    缺点:
    需要提前知道任务的数量。

    原理:其工作原理是赋给CountDownLatch一个计数值,普通的任务执行完毕后,调用countDown()执行计数值减一。最后执行的任务在调用方法的开始调用await()方法,这样整个任务会阻塞,直到这个计数值(Count)为零,才会继续执行。

    栗子:

    package my.thread.test;
    
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    
    	
    	class AnyTask implements Runnable{
    		
    		private CountDownLatch endTaskLatch;
    		
    		public AnyTask(CountDownLatch latch) {
    			
    			this.endTaskLatch = latch;
    			
    		}
    		
    		public void run() {
    			try {
    				Thread.sleep(10000);
    				System.out.println("普通任务执行执行完毕!");
    				endTaskLatch.countDown();
    				System.out.println(endTaskLatch.getCount());
    				
    			}catch(Exception e) {
    				
    				e.printStackTrace();
    				
    			}
    		}
    	}
    	
    class EndTask implements Runnable{
    		
    		private CountDownLatch endTaskLatch;
    		
    		EndTask(CountDownLatch latch) {
    			
    			this.endTaskLatch =latch;
    		}
    		
    		public void run() {
    			
    			try {
    				
    				endTaskLatch.await();
    				System.out.println("开始执行最终任务");
    				System.out.println(endTaskLatch.getCount());
    			}catch(Exception e) {
    				e.printStackTrace();
    				
    			}
    		}
    	}
    	
    public class CountDownLatchTest {
    
    	public static void main(String[] args) {
    		
    		ExecutorService exector = Executors.newFixedThreadPool(7);
    		CountDownLatch TaskLatch = new CountDownLatch(10);
    		EndTask endTask = new EndTask(TaskLatch);
    		
    		exector.execute(endTask);
    		
    		for(int i=0;i<10;i++) {
    			exector.execute(new AnyTask(TaskLatch));
    		}
    		System.out.println("主线程已经执行完了");	
    	}
    }
    
    

    根据打印结果我们可以清楚的看到你,endTask等待所有的AnyTask执行完毕才继续执行,否则会一直阻塞下去。

    当然,我们也可以使用await()一直阻塞。在主线程调用即可。

    三、使用重入锁,维持一个公共计数:

    第三种方式,实行起来基本上和CountDownLatch 的原理差不多。

    所有的普通任务维持一个static的计数器,当任务完成时计数器加一(这里要用锁),当计数器的值等于任务数时,这时所有的任务已经执行完毕了,这时endTask就会自动执行。

    所有的任务,包括endTask都可以放到线程池中,当普通任务未执行完毕时,如果endTask开始执行,也会一直阻塞等待,直到公共计数等于等于任务数。

    优点:灵活、可控
    缺点:需要预知运算的任务数、操作相对有点繁琐

    栗子:

    package my.thread.test;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class AnyTask implements Runnable{
    	
    	public static int taskNum = 0;
    	private Lock lock = new ReentrantLock();
    	
    	public void run() {
    		try {
    			Thread.sleep(3000);
    			
    			System.out.println("普通任务执行执行完毕!");
    			
    			lock.lock();
    			AnyTask.taskNum++;
    			lock.unlock();	
    		}catch(Exception e) {
    			
    			e.printStackTrace();
    			
    		}
    	}
    }
    
    class EndTask implements Runnable{
    	
    	private int tnum = 0;
    	public EndTask(int tnum) {
    		this.tnum = tnum;
    		
    	}
    	
    	public void run() {
    		
    		try {
    			while(true) {
    				if(tnum==AnyTask.taskNum) {
    			
    					System.out.println("开始执行最终任务");
    					break;
    					
    				}else {
    					System.out.println("线程池的任务没有完成,等待。。。");
    					Thread.sleep(3000);
    				}
    			}
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    			
    		}
    	}
    }
    
    public class JishuTest {
    	
    	public static void main(String[] args) {
    		
    		ExecutorService exector = Executors.newFixedThreadPool(7);
    		
    		int taskNum = 10;
    		
    		for(int i=0;i<taskNum;i++) {
    			
    			AnyTask anyTask = new AnyTask(); 
    			exector.execute(anyTask);
    			
    		}
    		EndTask endTask = new EndTask(taskNum);
    		exector.execute(endTask);
    		exector.shutdown();
    		
    	}
    }
    
    

    四、submit向线程池提交任务,Future判断任务执行状态:

    使用submit向线程池提交任务与execute提交不同,submit会有Future类型的返回值。通过返回返回值可以用于判断线程任务的执行状态。
    举例:

    package com.thread;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    	
    public class Test {
    
    	public static void main(String[] args) {
    		
    		ExecutorService exector = Executors.newFixedThreadPool(7);
    		Future<?> future = exector.submit(new Runnable(){
    			@Override
    			public void run() {
    				int i = 5;
    				while(i>=0) {
    					try {
    						System.out.println("正在执行线程!i="+i);
    						Thread.sleep(10000);
    						i--;
    					}catch(Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}	
    		});
    		while(true) {
    			if(future.isDone()) {
    				break;
    			}
    			System.out.println("主线程等待...");
    			try {
    				Thread.sleep(5000);
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    		System.out.println("主线程已经执行完了");	
    	}
    }
    

    打印日志:

    主线程等待...
    正在执行线程!i=5
    主线程等待...
    主线程等待...
    正在执行线程!i=4
    主线程等待...
    正在执行线程!i=3
    主线程等待...
    主线程等待...
    正在执行线程!i=2
    主线程等待...
    主线程等待...
    正在执行线程!i=1
    主线程等待...
    主线程等待...
    正在执行线程!i=0
    主线程等待...
    主线程等待...
    主线程已经执行完了
    
    

    不同的应用场景应采用适合的方式,以上、谢谢 !

    展开全文
  • 多线程并发,我们往往采用线程池来管理并发的线程。但是,我们往往有这样的需要:要求在线程池中的任务都完成后才能执行后续的任务,或者需要任务都完成后释放资源或向数据库写入状态。这些都需要我们判断线程池的...
  • 在JDK1.5中有getState()方法和Thread.State类可以判断线程的状态,但是现在老大说必须在1.4上实现多线程的一些功能,怎么才能在1.4上判断线程是否正常结束,是否是新线程……,??? [b]问题补充:[/b] 不好意思,可能...
  • 有一种解决方式,便是在子线程下载完成之后,都进行子线程的回调并判断是否所有子线程都已经执行完毕。 而CountDownLatch便是java在1.5提供的解决如上问题的工具类 阿里的ARouter的拦截器相关,就是用该工具类 概述 ...
  • 前言:多个线程同时查询一张表,最后汇总查询结果返回,那么就存在一个问题,如何判断多线程是否全部已经处理完成。 一、CountDownLatch简介 1、CountDownLatch概念 CountDownLatch是多线程控制的一种工具,它...
  • java 多线程知识

    2019-09-19 17:51:32
    Java 如何判断线程池所有任务是否执行完毕 http://blog.csdn.net/qishuo_java/article/details/50619981 转载于:https://...
  • 如何判断这些线程是否执行完毕,这里有一点讲究。如果靠主线程自己计数,就有可能在加一的过程中错过了某些 notify。所以需要由子线程完成的时候来给计数器加一。子线程之间是相互异步的,所以要用锁来同步这个...
  • 两个线程要交叉执行,所以可以用一个长度为101的数组(第一个位置不用,便于打印的数字和位置保持一致)保存每个线程的执行状态,一个线程执行完毕后在对应位置设置成1,之前前判断数组中前一个位置是否为...
  • java线程池概念.txt

    2019-08-16 10:14:03
    SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕 static final int STOP = 2;停止状态;此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务 static final int TERMINATED = 3;终止...
  • Linux 支持内核级的多线程 13.C++中什么数据分配在栈或堆中,New分配数据是在近堆还是远堆中? 答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理 堆: 程序运行时动态申请,new 和 malloc...
  • GetBinaryType 判断文件是否可以执行 GetCompressedFileSize 判断一个压缩文件在磁盘上实际占据的字节数 GetCurrentDirectory 在一个缓冲区中装载当前目录 GetDiskFreeSpace 获取与一个磁盘的组织有关的信息,...
  • FAQ(持续更新)

    2021-01-08 12:27:51
    这两个队列将近倾向于同时执行完毕。这个规律可以扩展到任意队列数量以及任意启动顺序。 为什么使用redis client时无需先建立连接 首先看一下redis client任务的创建接口: ~~~cpp class WFTaskFactory { ...
  • 这里010EBDB0 这个CALL负责检测注册码是否正确,正确返回1 否则返回0,由于 Enigma有多线程内联补丁保护因此不能 直接硬写此处代码,所以我们采用了硬件断点HOOK来实现。 1:定位PatchAddress: 先看此块内存...
  • C++程序员面试宝典

    热门讨论 2013-04-01 13:36:19
    面试题85 是否可以确定指针指向一个对象 90 面试题86 如何使用指针操作数组 90 面试题87 const对象的指针和const指针的区别 91 面试题88 数组指针与指针数组的区别 92 8.2 函数指针 93 面试题89 什么是函数指针?...
  • resin-jvm 调优

    2009-03-11 16:05:25
    并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序的可扩展性。 3.Sun HotSpot 1.4.1 JVM堆大小的调整 Sun HotSpot 1.4.1使用分代收集器...
  • X-Scan v3.1

    2018-10-22 08:43:03
    采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能,提供了图形界面和命令行两种操作方式,扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用服务漏洞、网络设备...
  • 能确保队列中的微任务在一次事件循环前被执行完毕 </li><li> 考虑兼容问题,vue 做了 microtask 向 macrotask 的降级方案 </li></ol> <h2>7. vue 是如何对数组方法进行变异的 ? 我们先来看看源码 <pre><code>js const...
  • X-Scan

    热门讨论 2008-04-04 15:19:43
    功能简介: <br> 采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能,提供了图形界面和命令行两种操作方式,扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用...
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
    像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java编写的显示器显示模式检测程序 2个目标文件 内容...
  • 像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java编写的显示器显示模式检测程序 2个目标文件 内容...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
    像坐标控制、旋转矩阵、定时器、生成图像、数据初始化、矩阵乘法、坐标旋转、判断是否是顺时针方向排列、鼠标按下、放开时的动作等,都可在本源码中得以体现。 Java编写的显示器显示模式检测程序 2个目标文件 内容...

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

如何判断多线程是否执行完毕