后台线程,线程组,线程池以及线程相关类详解
后台线程:
后台线程的概念是:有一种线程,是在后台运行的,它的任务是为其他的线程提供服务。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线程结束"); } }
其运行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
上述代码中,一个有两个线程,其中一个是后台线程,另外一个是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("主线程运行结束"); } }
运行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
新线程组线程组当前拥有的线程数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
值得注意的是,对线程组设置了优先级别,时候为后台线程组,只是关于该线程组的,不能代表线程组内的线程。真正设置线程是否为后台的还是需要调用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线程池,运行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
特殊的线程池: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(); } }
运行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
由于创建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(); } }
运行结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
---初始名 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
通常建议:如果多个线程之间需要共享资源,以达到线程之间的通信同能,就使用线程同步(同步机制);若仅仅需要隔离多个线程之间的共享冲突,则可以使用ThreadLocal
全部代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(); } }