后台线程,线程组,线程池以及线程相关类详解

后台线程:

后台线程的概念是:有一种线程,是在后台运行的,它的任务是为其他的线程提供服务。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

 

posted @ 2019-08-26 16:44  HJLのH  阅读(499)  评论(0编辑  收藏  举报