java 并发编程框架

线程组管理

线程组

  1. 线程的集合
  2. 大线程可包含小线程、
  3. 可管理多个线程,但效率较低
  4. 重复的创建线程和关闭线程
  5. 可通过enumerate显示所有线程

例:
使用线程组创建10个线程,每创建一个线程,休息1秒。
输出活跃的线程,所有线程列表。当活跃的线程数少于8个时,终止所有的线程。

其中,Reacher类为实现Runnable接口的类,Result类为一个存储数据的类。

package ThreadGroup;

import java.util.concurrent.TimeUnit;

public class Main {

	public static void main(String[] args) {
		ThreadGroup  threadgroup = new ThreadGroup("Peter");
		Result result = new Result(null);
		Reacher reacher = new Reacher(result);
		int i = 0;
		for(; i < 10; i++) {
			Thread thread = new Thread(threadgroup, reacher);
			thread.start();
			try {
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("=========线程组创建完成==========");
		
		System.out.println("活跃的线程数量为:" + threadgroup.activeCount());
		System.out.println("所有线程为:");
		threadgroup.list();
		System.out.println("===============================");
		
		Thread[] threads = new Thread[threadgroup.activeCount()];
		threadgroup.enumerate(threads);//将线程组中所有活跃的线程copy到数组中
		for(i = 0; i < threadgroup.activeCount(); i++)
			System.out.println(threads[i].getName() +": " + threads[i].getState());
		System.out.println("===============================");
		
		waitfinish(threadgroup);
		threadgroup.interrupt();
	}
	public static void waitfinish(ThreadGroup threadgroup) {
		while(threadgroup.activeCount() > 8) {
			try {
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}


package ThreadGroup;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class Reacher implements Runnable{
	private Result result;
	
	public Reacher(Result result) {
		this.result = result;
	}
	public void run() {
		String name = Thread.currentThread().getName();
		System.out.println("Thread" + name + "启动");
			try {
				doTask();
				result.setName(name);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
	private void doTask() throws InterruptedException {
		Random random = new Random((new Date()).getTime());
		int value = (int)(random.nextDouble()*50);
		System.out.printf("Thread %s : %d\n", Thread.currentThread().getName(), value);
		TimeUnit.SECONDS.sleep(value);
	}
}


package ThreadGroup;

public class Result {
	public String name;
	public Result(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Executor 框架

该框架可分离认任务的创建和任务的执行,线程可重复利用。(new开销大)

共享线程池:

  1. 预设好多个线程,多次执行多个小任务;
  2. 无需关心其他线程的执行过程;
  3. 任务创建与执行解耦合。

主要类:
ExecutorService,ThreadPoolExecutor,Future。
创建线程池:Executors.newCachedThreadPool/newFixedThreadPool。
线程池服务:ExecutorService。
具体的逻辑对象:Callable。
输出结果:Future。

例子:
main方法中:创建线程池,10个线程,创建线程安全的列表存储结果。
SumTask是一个实现Callable的接口。
(Callable与Runnabl基本一致,只是在实现的call方法中有返回值。)
SumTask类计算某一段的数据和,并返回。
依次创建并将该线程加入到线程池中。
当所有线程都完成后,计算总和。

package executor;
import java.util.concurrent.Future;
import java.util.ArrayList;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class TestTask {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(10);
		List<Future<Integer>> resultList = Collections.synchronizedList(new ArrayList<Future<Integer>>());
		int i;
		for(i = 0; i < 10; i++) {
			SumTask caculator = new SumTask(i*100+1, (i+1)*100 + 1);
			Future<Integer> result = executor.submit(caculator);
			resultList.add(result);
		}
		do {
			System.out.println("已完成的任务数:" + executor.getCompletedTaskCount());
			for(i = 0; i < resultList.size(); i++) {
				Future<Integer> result = resultList.get(i);
				System.out.printf("Task %d: %s\n", i, result.isDone());
				try {
					Thread.sleep(50);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}while(executor.getCompletedTaskCount() < resultList.size());
		
		int total = 0;
		for(i = 0; i < resultList.size(); i++) {
			Future<Integer> result = resultList.get(i);
			total += result.get();
		}
		System.out.println("1-1000的总和为:" + total);	
		executor.shutdown();
	}
}

package executor;

import java.util.concurrent.Callable;

public class SumTask implements Callable<Integer>{
	private int startNum;
	private int endNum;
	
	public SumTask(int startNum, int endNum) {
		this.startNum = startNum;
		this.endNum = endNum;
	}

	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for(int i = startNum; i < endNum+1; i++) {
			sum = sum + i;
		}
		System.out.println(Thread.currentThread().getName() + "的和为:" + sum);
		return sum;
	}
}

Fork-Join框架

该框架适用于整体任务量不确定的场合。实现分治编程(分解,治理合并)。

关键类:
ForkJoinPool:任务池。
定义具体的任务:
RecursiveAction,RecursiveTask。

框架实现步骤:

  1. 创建线程池;
  2. 创建任务;
  3. 提交任务,获取结果;
  4. 监视过程;
  5. 输出结果。

例子:
创建线程池,个数为8。
创建任务,并且提交任务,只需提交一次。

在SumTask线程中, 继承RecursiveTask,实现compute方法。
依照分解的思路逐步展开,并不断提交任务。

package ForkJoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;

public class MainTask {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ForkJoinPool pool =  new ForkJoinPool(8);
		SumTask task = new SumTask(1, 1000000);
		ForkJoinTask<Long> result = pool.submit(task);
		
		do {
			System.out.println("正在活跃的线程数:" + pool.getActiveThreadCount());
			System.out.println("正在并行的线程数:" + pool.getParallelism());	
			try {
				Thread.sleep(50);
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}while(!result.isDone());
		
		System.out.println("1-100000d的和为:" + result.get().toString());
	}
}

//任务线程
package ForkJoin;

import java.util.concurrent.RecursiveTask;

public class SumTask extends RecursiveTask<Long>{
	
	private static final long serialVersionUID = 1L;
	private int start;
	 private int end;
	 
	 public SumTask(int s, int e) {
		 start = s;
		 end = e;
	 }
	@Override
	protected Long compute() {
		Long sum = (long) 0;
		int threadhold = 4;
		if((end - start) < threadhold) {
			for(int i = start; i < end + 1; i++) 
				sum += i;
		}
		else {
			int mid = (end - start)/2 + start;
			SumTask task1 = new SumTask(start, mid);
			SumTask task2 = new SumTask(mid + 1, end);
			
			invokeAll(task1, task2);//提交自任务
			
			Long sum1 = task1.join();//等待子任务完成。
			Long sum2 = task2.join();
			
			sum = sum1 + sum2;
		}
		return sum;
	}	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值