zoukankan      html  css  js  c++  java
  • 后台线程,线程组,线程池以及线程相关类详解

    后台线程:

    后台线程的概念是:有一种线程,是在后台运行的,它的任务是为其他的线程提供服务。JVM的垃圾回收线程就是经典的后台线程。当整个虚拟机只剩下后台线程时,程序就没有继续运行的必要,虚拟机就退出来了。这里有个概念要说明一下,后台线程并不是等到前台线程执行完后才执行,而是跟前台线程一起执行。当前台线程执行完后,JVM通知后台死亡,哪怕后台还没有运行完,后台线程也死亡。

    创建后台线程和创建前台线程是一致的,只是在该线程运行前,执行Thread.setDaemon()方法。该方法传入boolean参数,true代表该线程是后台线程,false代表该线程是前台线程。Thread.isDaemon()方法,返回该线程是否是后台线程。true为后台线程,false为前台线程。

    public class Threads{
      public static void main(String[] args){
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for(int i=0;i<20;i++){
                        System.out.println(Thread.currentThread().getName()+"运行了"+i);
                    }
                }
            };
            Thread thread_1 = new Thread(runnable);
            thread_1.setDaemon(true);
            System.out.println(thread_1.getName()+"是否是后台线程:"+thread_1.isDaemon());
            thread_1.start();
            for(int i=0;i<20;i++){
                System.out.println(Thread.currentThread()+"运行了"+i);
            }
            System.out.println("main线程结束");
      }
    }

    其运行结果如下:

    Thread-0是否是后台线程:true
    Thread[main,5,main]运行了0
    Thread[main,5,main]运行了1
    Thread[main,5,main]运行了2
    Thread[main,5,main]运行了3
    Thread-0运行了0
    Thread[main,5,main]运行了4
    Thread-0运行了1
    Thread[main,5,main]运行了5
    Thread-0运行了2
    Thread[main,5,main]运行了6
    Thread-0运行了3
    Thread[main,5,main]运行了7
    Thread-0运行了4
    Thread[main,5,main]运行了8
    Thread-0运行了5
    Thread[main,5,main]运行了9
    Thread-0运行了6
    Thread[main,5,main]运行了10
    Thread-0运行了7
    Thread[main,5,main]运行了11
    Thread-0运行了8
    Thread[main,5,main]运行了12
    Thread-0运行了9
    Thread[main,5,main]运行了13
    Thread-0运行了10
    Thread[main,5,main]运行了14
    Thread-0运行了11
    Thread[main,5,main]运行了15
    Thread-0运行了12
    Thread[main,5,main]运行了16
    Thread-0运行了13
    Thread[main,5,main]运行了17
    Thread-0运行了14
    Thread[main,5,main]运行了18
    Thread-0运行了15
    Thread[main,5,main]运行了19
    main线程结束
    Thread-0运行了16
    Thread-0运行了17
    Thread-0运行了18
    Thread-0运行了19
    Thread-0运行了20
    Thread-0运行了21
    Thread-0运行了22
    Thread-0运行了23
    Thread-0运行了24
    Thread-0运行了25
    Thread-0运行了26
    Thread-0运行了27
    Thread-0运行了28
    Thread-0运行了29
    Thread-0运行了30
    Thread-0运行了31
    Thread-0运行了32
    Thread-0运行了33
    Thread-0运行了34
    View Code

    上述代码中,一个有两个线程,其中一个是后台线程,另外一个是main主线程,也是前台线程。查看运行结果可以方法,后台线程与前台线程是竞争执行的,但等到前台线程运行结束时,后台线程还未运行后便结束了。

    线程组:

    当我们创建了许多的线程时,我们可以通过将线程进行分组管理。然后我们只需对线程组进行控制,便可以控制该组内的线程。当然线程组提供的方法比较少,有以下方法:

       ThreadGroup.setDaemon(boolean); 设置线程组是否为后台线程组

       ThreadGroup.setMaxPriority(int); 设置线程组最高优先级

       ThreadGroup.interrip();              中断此线程组中的所有线程

    创建线程组使用的时ThreadGroup类,有以下的构造方法:

       ThreadGroup(String name);  创建一个空线程名称为name的线程组

       ThreadGroup(ThreadGroup parent;String name)  创建指定父线程组且名称为name的线程组

    线程添加到线程组的方式是通过线程创建时,传入线程组对象到线程的构造方法中。

       Thread(ThreadGroup threadGroup,Runnable target)

       Thread(ThreadGroup threadGroup,Runnable target,String name)

       Thread(ThreadGroup threadGroup,String name)

    public class Threads{
      public static void main(String[] args){
         ThreadGroup threadGroup
    = new ThreadGroup("新线程组"); System.out.println(threadGroup.getName()+"线程组当前拥有的线程数"+threadGroup.activeCount()); Runnable runnable = new Runnable(){ @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"执行了"+i); } } }; Thread thread_1 = new Thread(threadGroup, runnable); Thread thread_2 = new Thread(threadGroup,runnable);

              System.out.println("线程1是否是后台线程"+thread_1.isDaemon());
              System.out.println("线程2是否是后台线程"+thread_2.isDaemon());

            threadGroup.setDaemon(true);
            thread_1.start();thread_2.start();
            System.out.println(threadGroup.getName()+"线程组当前拥有的线程数"+threadGroup.activeCount());
            System.out.println(threadGroup.isDaemon());
            System.out.println("主线程运行结束");
      }
    }

    运行结果如下:

    新线程组线程组当前拥有的线程数0
    线程1是否是后台线程false
    线程2是否是后台线程false
    新线程组线程组当前拥有的线程数2
    true
    主线程运行结束
    Thread-0执行了0
    Thread-0执行了1
    Thread-0执行了2
    Thread-0执行了3
    Thread-0执行了4
    Thread-0执行了5
    Thread-0执行了6
    Thread-0执行了7
    Thread-1执行了0
    Thread-1执行了1
    Thread-1执行了2
    Thread-0执行了8
    Thread-1执行了3
    Thread-0执行了9
    Thread-1执行了4
    Thread-0执行了10
    Thread-1执行了5
    Thread-0执行了11
    Thread-1执行了6
    Thread-0执行了12
    Thread-0执行了13
    Thread-0执行了14
    Thread-0执行了15
    Thread-0执行了16
    Thread-0执行了17
    Thread-0执行了18
    Thread-0执行了19
    Thread-1执行了7
    Thread-1执行了8
    Thread-1执行了9
    Thread-1执行了10
    Thread-1执行了11
    Thread-1执行了12
    Thread-1执行了13
    Thread-1执行了14
    Thread-1执行了15
    Thread-1执行了16
    Thread-1执行了17
    Thread-1执行了18
    Thread-1执行了19
    View Code

    值得注意的是,对线程组设置了优先级别,时候为后台线程组,只是关于该线程组的,不能代表线程组内的线程。真正设置线程是否为后台的还是需要调用Thread.setDaemon方法

    线程池:

    由于系统创建线程并启动的程本是比较高的,为了提高性能。我们将多个线程放入指定的地方,当系统需要用到时,会从该地方取出线程,当该线程运行完毕后,不是结束该线程,而是放入了该地方。这样就可以减少线程的创建与销毁,提高了性能。我们将该地方叫做,由于放入的是线程,也叫线程池。

    Java 通过Executors工厂来产生线程池,提供以下静态工厂方法来创建线程池:

    1. newCachedThreadPool()                    创建一个带有缓存的线程池

    2. newFixedThreadPool(int nThreads)   创建一个可重用,固定线程数的线程池

    3. newSingleThreadPool()                      创建一个单线程可重用的线程池,相当于newFixedThreadPool方法传入参数1

    4. newScheduledThreadPool(int corePoolSize)       创建一个指定线程数的线程池,它可以在指定延迟后执行线程任务。

    5. newSingleThreadScheduledExecutor()                创建一个单线程的线程池,它可以在指定延迟后执行线程任务。相当于newScheduledThreadPool传入参数1

    6. ExecutorService newWorkStealingPool(int parallelism)       创建持有足够多的线程的线程池来支持给定的并行级别,该方法还会使用多个队列来减少竞争关系。

    7. ExecutorService newWorkStealingPool()                             该方法时上个方法的简化版。根据cpu的核数设置并行级别,相当于上个方法传入cpu核数

     上述方法中:

      前3个返回ExecutorService对象,该对象代表一个线程池。代表尽快执行线程的线程池(只要池中有空闲的线程,便会立刻执行线程任务)

        4和5返回ScheduledExecutorService对象,ScheduledExecutorService是ExecutorService的子类。

        6和7返回ExecutorService对象,是work stealing池,相当于后台线程池

    使用线程池来执行线程任务步骤如下:

       1. 调用Executors类的静态工厂方法创建线程池对象(ExecutorService,ScheduledExecutorService类)

       2. 创建线程实例,作为线程执行任务

       3. 调用ExecutorService.submit()方法来提交线程实例任务

           submit()方法一共有3种形式:

                 1.Future<?>  submit(Runnable task)    Future对象返回线程执行体的返回值,由于是用Runnable创建线程执行体没有返回值,因此返回null值

                 2.<T>Future<?> submit(Runnable task,T result)  该方法是上方法的延申,由于Runnable创建线程执行体没有返回值,因此将返回值写入submit方法中,当线程运行完毕时,返回submit的result参数,因此Future会得到result值

                 3.<T>Future<?> submit(Callable<T>)  该方法是使用Callable方法创建线程执行体,线程执行完毕后,返回call方法值给Future。

            Future对象不仅仅是代表线程执行体的返回值,也可以通过该对象调用isDone()和isCancelled()方法来获得线程对象的执行状态

         除了调用submit方法之外,ScheduleExecutorService类还可以调用以下4种方法来提交线程实例任务

      1. ScheduledFuture<V> schedule(Callable<V> callable,long delay,TimeUnit unit)  指定callable任务将在delay延迟后执行

           2. ScheduledFuture<?> schedule(Runnable command,long delay,TimeUnit unit)   指定command任务将在delay延迟后执行

           3. ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)  指定command任务在delay延迟后执行,并且设定频率重复执行

           4. ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit) 指定command任务在delay延迟后执行,并设定频率重复执行,且重复执行前先延迟delay

           TimeUnit是时间工具类,像了解的可以查看该网址: https://www.cnblogs.com/zhaoyanjun/p/5486726.html

     4. 当线程池不想在执行任何线程任务时,调用ExecutorService.shutdown()方法,执行该方法后,线程池不在提交线程任务,等待现有线程任务执行完毕时,关闭线程池。也可以使用ExecutorService.shutdownNow()方法,停止正在运行线程任务,暂停处理正在等待的任务,关闭线程池,并返回等待执行的任务列表

    public class Threads{
      public static void main(String[] args){
            //创建线程池
            ExecutorService pool_executor = Executors.newFixedThreadPool(6);
            ExecutorService pool_work = Executors.newWorkStealingPool();
            ScheduledExecutorService pool_scheduled = Executors.newScheduledThreadPool(6);
            //创建Runnable线程执行体
            Runnable target_1 =() ->{
                for(int i=0;i<10;i++){
                    System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
                }
            };
            Runnable target_2 = () ->{
                for(int i=0;i<10;i++){
                    System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
                }
            };
            Runnable target_3 = () ->{
                for(int i=0;i<1000;i++){
                    System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
                }
            };
            //放入两个线程到ScheduledExecutorService线程池种,其中一个延迟2毫秒执行,另外一个延迟5毫秒执行
            ScheduledFuture scheduledFuture_1 = pool_scheduled.schedule(target_2, 2,TimeUnit.MILLISECONDS);
            ScheduledFuture scheduledFuture_2 = pool_scheduled.schedule(target_2, 5,TimeUnit.MILLISECONDS);
            //提交两个线程到ExecutorService线程池中
            Future executorFuture_1 = pool_executor.submit(target_1);
            Future executorFuture_2 = pool_executor.submit(target_1);
            //提交两个线程到work stealing线程池中
            Future workFuture_1 = pool_work.submit(target_3);
            Future workFuture_2 = pool_work.submit(target_3);
            
            //关闭线程池
            pool_executor.shutdown();
            pool_work.shutdown();
            pool_scheduled.shutdown();
      }
    }

    上述代码中创建了3个线程池,一个ExecutorService 线程池,一个ScheduledExecutorService线程池,还有一个work stealing线程池,运行结果如下:

    pool-1-thread-1的i值为:0
    pool-1-thread-1的i值为:1
    pool-1-thread-1的i值为:2
    pool-1-thread-1的i值为:3
    pool-1-thread-2的i值为:0
    pool-1-thread-1的i值为:4
    pool-1-thread-2的i值为:1
    pool-1-thread-1的i值为:5
    pool-1-thread-2的i值为:2
    pool-1-thread-1的i值为:6
    pool-1-thread-2的i值为:3
    pool-1-thread-1的i值为:7
    pool-1-thread-2的i值为:4
    pool-1-thread-1的i值为:8
    pool-1-thread-2的i值为:5
    pool-1-thread-2的i值为:6
    pool-1-thread-2的i值为:7
    pool-1-thread-2的i值为:8
    pool-1-thread-2的i值为:9
    pool-1-thread-1的i值为:9
    pool-2-thread-1的i值为:0
    pool-2-thread-1的i值为:1
    pool-2-thread-1的i值为:2
    pool-2-thread-1的i值为:3
    pool-2-thread-1的i值为:4
    pool-2-thread-1的i值为:5
    pool-2-thread-1的i值为:6
    pool-2-thread-1的i值为:7
    pool-2-thread-1的i值为:8
    pool-2-thread-1的i值为:9
    ForkJoinPool-1-worker-1的i值为:0
    ForkJoinPool-1-worker-1的i值为:1
    ForkJoinPool-1-worker-2的i值为:0
    ForkJoinPool-1-worker-1的i值为:2
    ForkJoinPool-1-worker-2的i值为:1
    ForkJoinPool-1-worker-1的i值为:3
    ForkJoinPool-1-worker-2的i值为:2
    ForkJoinPool-1-worker-1的i值为:4
    ForkJoinPool-1-worker-2的i值为:3
    ForkJoinPool-1-worker-1的i值为:5
    ForkJoinPool-1-worker-2的i值为:4
    ForkJoinPool-1-worker-2的i值为:5
    ForkJoinPool-1-worker-2的i值为:6
    ForkJoinPool-1-worker-1的i值为:6
    ForkJoinPool-1-worker-1的i值为:7
    ForkJoinPool-1-worker-2的i值为:7
    ForkJoinPool-1-worker-2的i值为:8
    ForkJoinPool-1-worker-2的i值为:9
    ForkJoinPool-1-worker-2的i值为:10
    ForkJoinPool-1-worker-2的i值为:11
    ForkJoinPool-1-worker-1的i值为:8
    ForkJoinPool-1-worker-1的i值为:9
    ForkJoinPool-1-worker-1的i值为:10
    ForkJoinPool-1-worker-2的i值为:12
    ForkJoinPool-1-worker-1的i值为:11
    ForkJoinPool-1-worker-2的i值为:13
    ForkJoinPool-1-worker-2的i值为:14
    ForkJoinPool-1-worker-2的i值为:15
    ForkJoinPool-1-worker-2的i值为:16
    ForkJoinPool-1-worker-2的i值为:17
    ForkJoinPool-1-worker-2的i值为:18
    ForkJoinPool-1-worker-2的i值为:19
    ForkJoinPool-1-worker-2的i值为:20
    ForkJoinPool-1-worker-2的i值为:21
    ForkJoinPool-1-worker-1的i值为:12
    ForkJoinPool-1-worker-1的i值为:13
    ForkJoinPool-1-worker-1的i值为:14
    ForkJoinPool-1-worker-2的i值为:22
    ForkJoinPool-1-worker-2的i值为:23
    ForkJoinPool-1-worker-2的i值为:24
    ForkJoinPool-1-worker-2的i值为:25
    ForkJoinPool-1-worker-2的i值为:26
    ForkJoinPool-1-worker-2的i值为:27
    ForkJoinPool-1-worker-1的i值为:15
    ForkJoinPool-1-worker-1的i值为:16
    ForkJoinPool-1-worker-1的i值为:17
    ForkJoinPool-1-worker-1的i值为:18
    ForkJoinPool-1-worker-1的i值为:19
    ForkJoinPool-1-worker-1的i值为:20
    ForkJoinPool-1-worker-1的i值为:21
    ForkJoinPool-1-worker-1的i值为:22
    ForkJoinPool-1-worker-1的i值为:23
    ForkJoinPool-1-worker-1的i值为:24
    ForkJoinPool-1-worker-1的i值为:25
    ForkJoinPool-1-worker-1的i值为:26
    ForkJoinPool-1-worker-1的i值为:27
    ForkJoinPool-1-worker-1的i值为:28
    ForkJoinPool-1-worker-1的i值为:29
    ForkJoinPool-1-worker-1的i值为:30
    ForkJoinPool-1-worker-1的i值为:31
    ForkJoinPool-1-worker-1的i值为:32
    ForkJoinPool-1-worker-1的i值为:33
    ForkJoinPool-1-worker-1的i值为:34
    ForkJoinPool-1-worker-1的i值为:35
    ForkJoinPool-1-worker-1的i值为:36
    ForkJoinPool-1-worker-1的i值为:37
    ForkJoinPool-1-worker-1的i值为:38
    ForkJoinPool-1-worker-1的i值为:39
    ForkJoinPool-1-worker-1的i值为:40
    ForkJoinPool-1-worker-1的i值为:41
    ForkJoinPool-1-worker-1的i值为:42
    ForkJoinPool-1-worker-1的i值为:43
    ForkJoinPool-1-worker-1的i值为:44
    ForkJoinPool-1-worker-1的i值为:45
    ForkJoinPool-1-worker-1的i值为:46
    ForkJoinPool-1-worker-1的i值为:47
    ForkJoinPool-1-worker-1的i值为:48
    ForkJoinPool-1-worker-2的i值为:28
    ForkJoinPool-1-worker-2的i值为:29
    ForkJoinPool-1-worker-2的i值为:30
    ForkJoinPool-1-worker-2的i值为:31
    ForkJoinPool-1-worker-2的i值为:32
    ForkJoinPool-1-worker-2的i值为:33
    ForkJoinPool-1-worker-2的i值为:34
    ForkJoinPool-1-worker-2的i值为:35
    ForkJoinPool-1-worker-2的i值为:36
    ForkJoinPool-1-worker-2的i值为:37
    ForkJoinPool-1-worker-2的i值为:38
    pool-2-thread-1的i值为:0
    pool-2-thread-1的i值为:1
    pool-2-thread-1的i值为:2
    pool-2-thread-1的i值为:3
    pool-2-thread-1的i值为:4
    pool-2-thread-1的i值为:5
    pool-2-thread-1的i值为:6
    ForkJoinPool-1-worker-2的i值为:39
    ForkJoinPool-1-worker-2的i值为:40
    ForkJoinPool-1-worker-2的i值为:41
    ForkJoinPool-1-worker-2的i值为:42
    ForkJoinPool-1-worker-1的i值为:49
    ForkJoinPool-1-worker-1的i值为:50
    ForkJoinPool-1-worker-1的i值为:51
    ForkJoinPool-1-worker-2的i值为:43
    ForkJoinPool-1-worker-2的i值为:44
    ForkJoinPool-1-worker-2的i值为:45
    ForkJoinPool-1-worker-2的i值为:46
    ForkJoinPool-1-worker-2的i值为:47
    ForkJoinPool-1-worker-2的i值为:48
    ForkJoinPool-1-worker-2的i值为:49
    ForkJoinPool-1-worker-2的i值为:50
    ForkJoinPool-1-worker-2的i值为:51
    pool-2-thread-1的i值为:7
    pool-2-thread-1的i值为:8
    pool-2-thread-1的i值为:9
    ForkJoinPool-1-worker-2的i值为:52
    ForkJoinPool-1-worker-2的i值为:53
    ForkJoinPool-1-worker-2的i值为:54
    ForkJoinPool-1-worker-2的i值为:55
    ForkJoinPool-1-worker-2的i值为:56
    ForkJoinPool-1-worker-2的i值为:57
    ForkJoinPool-1-worker-2的i值为:58
    ForkJoinPool-1-worker-2的i值为:59
    ForkJoinPool-1-worker-2的i值为:60
    ForkJoinPool-1-worker-2的i值为:61
    ForkJoinPool-1-worker-2的i值为:62
    ForkJoinPool-1-worker-2的i值为:63
    ForkJoinPool-1-worker-2的i值为:64
    ForkJoinPool-1-worker-2的i值为:65
    ForkJoinPool-1-worker-2的i值为:66
    ForkJoinPool-1-worker-2的i值为:67
    ForkJoinPool-1-worker-2的i值为:68
    ForkJoinPool-1-worker-2的i值为:69
    ForkJoinPool-1-worker-2的i值为:70
    ForkJoinPool-1-worker-2的i值为:71
    ForkJoinPool-1-worker-2的i值为:72
    ForkJoinPool-1-worker-2的i值为:73
    View Code

    特殊的线程池:ForkJoinPool

    ForkJoinPool是ExecutorService的实现类,支持将一个任务拆分成多个小任务并并发执行,充分利用多核cpu的优势

    ForkJoinPool的构造方法有如下两种:

       ForkJoinPool(int parallelism) 创建一个包含parallelism个并行线程的ForkJoinPool

       ForkJoinPool():以Runtime.avaiableProcessors()方法值作为parallelism作为参数创建ForkJoinPool

    调用submit(ForkJoinTask task)或者invoke(ForkJoinTask task)方法来执行指定任务。

       ForkJoinTask是一个抽象类,代表一个可以并行,合并的任务。它还有两个子抽象类,RecursiveAction和RecursiveTask。其中RecursiveAction代表没有返回值的任务,可以理解为Run方法,RecursiveTask有返回值,可以理解为call方法。

    因此,如要使用ForkJoinPool线程池,需要创建继承RecursiveAction与RecursiveTask的实现类,重现compute()方法

     以下代码以打印300个数值为一个大任务,将这个大任务根据每个任务最多执行50个值进行拆分,拆分规则为开始数与结束数对半拆分,直到开始数与结束数只差小于等于50

    class PrintTask extends RecursiveAction{
        //每个任务最多打印50个数
        private static final int THRESHOLD = 50;
        private int start;
        private int end;
        
        public PrintTask(int start,int end){
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected void compute() {
            // TODO Auto-generated method stub
            /**
             * 判断当前任务开始数与结束数之差是否小于等于50个数
             * 若符合,执行该任务
             * 若不符合,将开始数与结束数之差折半并分成两个任务执行
             * */
            if((end-start)<=THRESHOLD){
                for(int i=start;i<end;i++){
                    System.out.println(Thread.currentThread()+"打印了数值:"+i);
                }
            }else{
                int middle = (start+end)/2;
                PrintTask left = new PrintTask(start,middle);
                PrintTask right = new PrintTask(middle,end);
                //fork方法,并发执行
                left.fork();
                right.fork();
            }
        }
    }
    
    public class Threads{
      public static void main(String[] args){
            ForkJoinPool forkJoinPool = new ForkJoinPool();
            forkJoinPool.submit(new PrintTask(0, 300));
            try{
                forkJoinPool.awaitTermination(2, TimeUnit.SECONDS);
            }catch(Exception e){}
            forkJoinPool.shutdown();
      }
    }

    运行结果如下:

    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:187
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:262
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:37
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:112
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:38
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:263
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:188
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:264
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:39
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:113
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:40
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:265
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:189
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:266
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:41
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:114
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:42
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:267
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:190
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:268
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:43
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:115
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:116
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:44
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:269
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:191
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:192
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:270
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:45
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:117
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:46
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:271
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:193
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:272
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:47
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:118
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:48
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:273
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:194
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:274
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:49
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:119
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:50
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:275
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:195
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:276
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:51
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:120
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:52
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:277
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:196
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:278
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:53
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:121
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:54
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:279
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:197
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:280
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:55
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:122
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:56
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:281
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:282
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:198
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:199
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:200
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:201
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:202
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:203
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:283
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:284
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:285
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:57
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:123
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:58
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:286
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:204
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:287
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:59
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:124
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:60
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:288
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:205
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:289
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:61
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:125
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:62
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:290
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:206
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:291
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:63
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:126
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:64
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:292
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:207
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:293
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:65
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:127
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:66
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:294
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:208
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:295
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:67
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:128
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:68
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:296
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:209
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:297
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:69
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:129
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:70
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:298
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:210
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:299
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:71
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:130
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:72
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:225
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:211
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:226
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:73
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:131
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:74
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:227
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:212
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:228
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:0
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:132
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:1
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:229
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:213
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:230
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:2
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:133
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:3
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:231
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:214
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:232
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:4
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:134
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:5
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:233
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:215
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:234
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:6
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:135
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:7
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:235
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:216
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:236
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:8
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:136
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:9
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:237
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:217
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:238
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:10
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:137
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:11
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:239
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:218
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:240
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:12
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:138
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:13
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:241
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:219
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:242
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:14
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:139
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:15
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:243
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:220
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:244
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:16
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:140
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:17
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:245
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:221
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:246
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:18
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:141
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:19
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:247
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:222
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:248
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:20
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:142
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:21
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:249
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:223
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:250
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:22
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:143
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:23
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:251
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:224
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:252
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:24
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:144
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:25
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:253
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:150
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:254
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:26
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:145
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:27
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:255
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:151
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:256
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:28
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:146
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:29
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:257
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:152
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:258
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:259
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:260
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:261
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:30
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:147
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:31
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:75
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:153
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:76
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:32
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:148
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:33
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:77
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:154
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:78
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:79
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:80
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:34
    Thread[ForkJoinPool-1-worker-2,5,main]打印了数值:149
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:35
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:81
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:155
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:82
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:83
    Thread[ForkJoinPool-1-worker-0,5,main]打印了数值:36
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:84
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:156
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:85
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:157
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:86
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:158
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:87
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:159
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:88
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:160
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:89
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:161
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:90
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:162
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:91
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:163
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:92
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:164
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:93
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:94
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:95
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:96
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:165
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:97
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:98
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:99
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:100
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:166
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:101
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:167
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:168
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:169
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:170
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:171
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:172
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:173
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:174
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:102
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:175
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:176
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:177
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:178
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:179
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:180
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:181
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:182
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:183
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:103
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:184
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:185
    Thread[ForkJoinPool-1-worker-3,5,main]打印了数值:186
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:104
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:105
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:106
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:107
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:108
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:109
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:110
    Thread[ForkJoinPool-1-worker-1,5,main]打印了数值:111
    View Code

    由于创建ForkJoinPool没有传入参数,以Runtime.availableProcessors()返回值的作为参数,我的电脑cpu是4核数,因此并发是4个线程。以上是没有返回值的大任务,下面创建一个有返回值的任务,对一个数组长度为100进行累加,每个任务只能累加20次。

    class callTask extends RecursiveTask{
        //每个任务最多累加20次
        private static final int THRESHOLD = 20;
        private int arr[];
        private int start;
        private int end;
        
        public callTask(int arr[],int start,int end){
            this.arr = arr;
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected Integer compute() {
            // TODO Auto-generated method stub
            /**
             * 判断当前任务累加次数是否小于等于20次
             * 若符合,执行该任务
             * 若不符合,对半拆分 
             * */
            int sum = 0;
            if((end-start)<THRESHOLD){
                for(int i=start;i<end;i++){
                    sum += arr[i];
                }
                return sum;
            }else{
                int middle = (start+end)/2;
                callTask left = new callTask(arr,start,middle);
                callTask right = new callTask(arr,middle,end);
                //fork方法,并发执行
                left.fork();
                right.fork();
                return (int)left.join()+(int)right.join();
            }
        }
    }
    public class Threads{   public static void main(String[] args){ int[] arr = new int[100]; Random rand = new Random(); int total = 0; for(int i=0;i<arr.length;i++){ //随机创建一个数 int tep = rand.nextInt(20); //赋值给对应数组,并进行累加 arr[i] = tep; total +=tep; } System.out.println("不通过拆分任务合为:"+total); ForkJoinPool forkJoinPoolCall = new ForkJoinPool(); Future<Integer> future = forkJoinPoolCall.submit(new callTask(arr,0, arr.length)); try{ System.out.println("通过拆分任务合为:"+future.get()); }catch(Exception e){} forkJoinPoolCall.shutdown();   } }

    运行结果如下:

    不通过拆分任务合为:921
    通过拆分任务合为:921

    线程相关类

     ThreadLocal类:线程局部变量,作用是为每个使用该变量的都提供一个变量值的副本,使每个线程都可以独立低改变自己的副本,不会和其他线程的副本冲突。

     ThreadLocal类的使用方法:

      1. T get()方法,返回此线程局部变量中当前线程副本中的值

      2.void remove()方法,删除此线程局部变量中当前线程的值  

      3.void set()方法,设置此线程局部变量中当前线程副本中的值

    class Account{
        private ThreadLocal<String> name = new ThreadLocal<>();
        public Account(String str){
            this.name.set(str);
            System.out.println("---"+this.name.get());
        }
        public String getName(){
            return this.name.get();
        }
        public void setName(String str){
            this.name.set(str);
        }
    }
    class myThread extends Thread{
        private Account account;
        public myThread(Account account,String name){
            super(name);
            this.account = account;
        }
        
        public void run(){
            for(int i=0;i<10;i++){
                if(i==6){
                    account.setName(getName());
                }
                System.out.println(account.getName()+"账户的i值:"+i);
            }
        }
    }
    public class Threads{
      public void static main(String[] args){
            Account ac = new Account("初始名");
            new myThread(ac,"线程甲").start();
            new myThread(ac,"线程乙").start();
      }
    }

    运行结果如下:

    ---初始名
    null账户的i值:0
    null账户的i值:0
    null账户的i值:1
    null账户的i值:1
    null账户的i值:2
    null账户的i值:3
    null账户的i值:4
    null账户的i值:5
    null账户的i值:2
    null账户的i值:3
    null账户的i值:4
    null账户的i值:5
    线程甲账户的i值:6
    线程甲账户的i值:7
    线程甲账户的i值:8
    线程甲账户的i值:9
    线程乙账户的i值:6
    线程乙账户的i值:7
    线程乙账户的i值:8
    线程乙账户的i值:9
    View Code

    通常建议:如果多个线程之间需要共享资源,以达到线程之间的通信同能,就使用线程同步(同步机制);若仅仅需要隔离多个线程之间的共享冲突,则可以使用ThreadLocal

    全部代码:

    class PrintTask extends RecursiveAction{
        //每个任务最多打印50个数
        private static final int THRESHOLD = 50;
        private int start;
        private int end;
        
        public PrintTask(int start,int end){
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected void compute() {
            // TODO Auto-generated method stub
            /**
             * 判断当前任务开始数与结束数之差是否小于等于50个数
             * 若符合,执行该任务
             * 若不符合,将开始数与结束数之差折半并分成两个任务执行
             * */
            if((end-start)<=THRESHOLD){
                for(int i=start;i<end;i++){
                    System.out.println(Thread.currentThread()+"打印了数值:"+i);
                }
            }else{
                int middle = (start+end)/2;
                PrintTask left = new PrintTask(start,middle);
                PrintTask right = new PrintTask(middle,end);
                //fork方法,并发执行
                left.fork();
                right.fork();
            }
        }
    }
    
    class callTask extends RecursiveTask{
        //每个任务最多累加20次
        private static final int THRESHOLD = 20;
        private int arr[];
        private int start;
        private int end;
        
        public callTask(int arr[],int start,int end){
            this.arr = arr;
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected Integer compute() {
            // TODO Auto-generated method stub
            /**
             * 判断当前任务累加次数是否小于等于20次
             * 若符合,执行该任务
             * 若不符合,对半拆分 
             * */
            int sum = 0;
            if((end-start)<THRESHOLD){
                for(int i=start;i<end;i++){
                    sum += arr[i];
                }
                return sum;
            }else{
                int middle = (start+end)/2;
                callTask left = new callTask(arr,start,middle);
                callTask right = new callTask(arr,middle,end);
                //fork方法,并发执行
                left.fork();
                right.fork();
                return (int)left.join()+(int)right.join();
            }
        }
    }
    class Account{
        private ThreadLocal<String> name = new ThreadLocal<>();
        public Account(String str){
            this.name.set(str);
            System.out.println("---"+this.name.get());
        }
        public String getName(){
            return this.name.get();
        }
        public void setName(String str){
            this.name.set(str);
        }
    }
    class myThread extends Thread{
        private Account account;
        public myThread(Account account,String name){
            super(name);
            this.account = account;
        }
        
        public void run(){
            for(int i=0;i<10;i++){
                if(i==6){
                    account.setName(getName());
                }
                System.out.println(account.getName()+"账户的i值:"+i);
            }
        }
    }
    
    public class Threads{
        public static void main(String[] args){
            /**
             * 后台线程
             * */
    //        Runnable runnable = new Runnable(){
    //            @Override
    //            public void run() {
    //                // TODO Auto-generated method stub
    //                for(int i=0;i<100;i++){
    //                    System.out.println(Thread.currentThread().getName()+"运行了"+i);
    //                }
    //            }
    //        };
    //        Thread thread_1 = new Thread(runnable);
    //        thread_1.setDaemon(true);
    //        System.out.println(thread_1.getName()+"是否是后台线程:"+thread_1.isDaemon());
    //        thread_1.start();
    //        for(int i=0;i<20;i++){
    //            System.out.println(Thread.currentThread()+"运行了"+i);
    //        }
    //        System.out.println("main线程结束");
            
            /**
             * 线程组
             * */
    //        ThreadGroup threadGroup = new ThreadGroup("新线程组");
    //        System.out.println(threadGroup.getName()+"线程组当前拥有的线程数"+threadGroup.activeCount());
    //        Runnable runnable = new Runnable(){
    //            @Override
    //            public void run() {
    //                // TODO Auto-generated method stub
    //                for(int i=0;i<20;i++){
    //                    System.out.println(Thread.currentThread().getName()+"执行了"+i);
    //                }
    //            }
    //        };
    //        Thread thread_1 = new Thread(threadGroup, runnable);
    //        Thread thread_2 = new Thread(threadGroup,runnable);
    //        threadGroup.setDaemon(true);
    //        System.out.println("线程1是否是后台线程"+thread_1.isDaemon());
    //        System.out.println("线程2是否是后台线程"+thread_2.isDaemon());
    //        thread_1.start();thread_2.start();
    //        System.out.println(threadGroup.getName()+"线程组当前拥有的线程数"+threadGroup.activeCount());
    //        System.out.println(threadGroup.isDaemon());
    //        System.out.println("主线程运行结束");
            
            /**
             * 线程池
             * */
    //        //创建线程池
    //        ExecutorService pool_executor = Executors.newFixedThreadPool(6);
    //        ExecutorService pool_work = Executors.newWorkStealingPool();
    //        ScheduledExecutorService pool_scheduled = Executors.newScheduledThreadPool(6);
    //        //创建Runnable线程执行体
    //        Runnable target_1 =() ->{
    //            for(int i=0;i<10;i++){
    //                System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
    //            }
    //        };
    //        Runnable target_2 = () ->{
    //            for(int i=0;i<10;i++){
    //                System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
    //            }
    //        };
    //        Runnable target_3 = () ->{
    //            for(int i=0;i<1000;i++){
    //                System.out.println(Thread.currentThread().getName()+"的i值为:"+i);
    //            }
    //        };
    //        //放入两个线程到ScheduledExecutorService线程池种,其中一个延迟2毫秒执行,另外一个延迟5毫秒执行
    //        ScheduledFuture scheduledFuture_1 = pool_scheduled.schedule(target_2, 2,TimeUnit.MILLISECONDS);
    //        ScheduledFuture scheduledFuture_2 = pool_scheduled.schedule(target_2, 5,TimeUnit.MILLISECONDS);
    //        //提交两个线程到ExecutorService线程池中
    //        Future executorFuture_1 = pool_executor.submit(target_1);
    //        Future executorFuture_2 = pool_executor.submit(target_1);
    //        //提交两个线程到work stealing线程池中
    //        Future workFuture_1 = pool_work.submit(target_3);
    //        Future workFuture_2 = pool_work.submit(target_3);
    //        
    //        //关闭线程池
    //        pool_executor.shutdown();
    //        pool_work.shutdown();
    //        pool_scheduled.shutdown();
            
            /**
             * ForkJoinPool RecursiveAction
             * */
    //        ForkJoinPool forkJoinPool = new ForkJoinPool();
    //        forkJoinPool.submit(new PrintTask(0, 300));
    //        try{
    //            forkJoinPool.awaitTermination(2, TimeUnit.SECONDS);
    //        }catch(Exception e){}
    //        forkJoinPool.shutdown();
            
            /**
             * ForkJoinPool RecursiveTask
             * */
    //        int[] arr = new int[100];
    //        Random rand = new Random();
    //        int total = 0;
    //        for(int i=0;i<arr.length;i++){
    //            //随机创建一个数
    //            int tep = rand.nextInt(20);
    //            //赋值给对应数组,并进行累加
    //            arr[i] = tep;
    //            total +=tep;
    //        }
    //        System.out.println("不通过拆分任务合为:"+total);
    //        ForkJoinPool forkJoinPoolCall = new ForkJoinPool();
    //        Future<Integer> future = forkJoinPoolCall.submit(new callTask(arr,0, arr.length));
    //        try{
    //            System.out.println("通过拆分任务合为:"+future.get());
    //        }catch(Exception e){}
    //        forkJoinPoolCall.shutdown();
            
            /**
             * ThreadLocal
             * */
            Account ac = new Account("初始名");
            new myThread(ac,"线程甲").start();
            new myThread(ac,"线程乙").start();
        }
    }
    View Code
  • 相关阅读:
    _CrtSetBreakAlloc(…)来检测内存泄漏+VC使用CRT调试功能检测内存泄漏(转)
    VC 2005 解决方案的目录结构设置和管理
    ArcGIS Engine基础开发教程(转)
    vc++实现avi文件的操作 用于视频解析及录制(转)
    微软免费杀毒软件下周二公测 年底推简体中文版 狼人:
    大量用户升级iPhone3.0系统导致苹果服务器故障 狼人:
    苹果发布45个iPhone和iTouch漏洞补丁 狼人:
    “汉网热血三国”“南方电视台”等网站被挂马 狼人:
    WAPI有望晋身国际标准 最大阻力美国首度支持 狼人:
    前Google员工推云安全服务检测网站挂马 狼人:
  • 原文地址:https://www.cnblogs.com/hjlin/p/11413442.html
Copyright © 2011-2022 走看看