线程组和线程池的学习

线程组:表示一个线程的集合。此外,线程组也可以包含其他线程组 

    线程对象在start()执行完毕,JVM调用完run()方法之后,此时线程类对象会变成垃圾,等待垃圾回收器回收。

线程池:线程在执行完毕后不会变成垃圾,而是重新回到线程池中,等待被利用。(某个线程执行完毕,反复利用线程对象)

public class MyThread implements Runnable {

	@Override
	public void run() {
		for(int x = 0 ; x <100 ; x ++) {
			System.out.println(Thread.currentThread().getName()+":"+x);
		}
	}
}
public class ThreadGroupDemo {
	
	public static void main(String[] args) {
		
		//获取线程组的名称	
		//method1();
		
		//给多个线程设置一个线程组名称
		method2();
	}

	private static void method2() {
		//public ThreadGroup(String name)构造一个新线程组
		ThreadGroup tg = new ThreadGroup("main-新的线程组") ;
		
		MyThread my = new MyThread() ;
		
		//Thread(ThreadGroup group, Runnable target, String name) 
		Thread t1 = new Thread(tg, my, "线程1") ;
		Thread t2 = new Thread(tg, my, "线程2") ;
		
		//直接获取线程组名称
		System.out.println(t1.getThreadGroup().getName());
		System.out.println(t2.getThreadGroup().getName());
	}

	private static void method1() {
		MyThread my = new MyThread() ;
		
		//创建线程类对象
		Thread t1 = new Thread(my, "线程1") ;
		Thread t2 = new Thread(my, "线程2") ;
		
		//public final ThreadGroup getThreadGroup()返回该线程所属的线程组
		ThreadGroup tg1 = t1.getThreadGroup() ;
		ThreadGroup tg2 = t2.getThreadGroup() ;
		
		//public final String getName():返回线程组的名称
		System.out.println(tg1.getName()); //main
		System.out.println(tg2.getName());//main
		
		//所有的线程它默认的线程组名称:main(主线程)
		System.out.println(Thread.currentThread().getThreadGroup().getName());//main
	}
}
和线程池有关的类
Executors: 一种工厂类
方法:
和线程池的创建有关系
public static ExecutorService newFixedThreadPool(int nThreads)
创建一个可重用固定线程数的线程池

ExecutorService:可以执行异步任务
创建一个线程池,执行接口中的方法
提交:Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task)提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future
Future:接口
Future 表示异步计算的结果
线程池调用完毕可以关闭的

void shutdown():关闭之前,会提交刚才的任务

public class MyRunnable implements Runnable {

	@Override
	public void run() {
		for(int x = 0 ; x < 100 ; x ++) {
			System.out.println(Thread.currentThread().getName()+":"+x);
		}
	}
}
public class ExceutorsDemo {
	
	public static void main(String[] args) {
		
		//创建一个线程池
		ExecutorService pool = Executors.newFixedThreadPool(2) ;//创建一个线程池中包含了2条线程
		
		//提交和Runnable接口的方法或者Callable(提交任务)
		pool.submit( new MyRunnable()) ;
		pool.submit( new MyRunnable()) ;
		
		//pool-1-thread-2 :线程池-池数-线程类对象的描述-编号(从1开始)

		//关闭线程池
		pool.shutdown();
		
	}
}


多线程实现方式第三种:

前提:自定义类实现Callable接口
1)创建线程池对象: Executors 里面的那个方法,返回的是ExecutorsService
2) 然后调用ExecutorsService里面的提交任务的方法
<T> Future<T> submit(Callable<T> task)提交一个返回值的任务用于执行
3)关闭线程池

//Callable的泛型的类型它是call方法的返回值类型
public class MyCallable implements Callable {

	@Override
	public Object call() throws Exception {
		for(int x = 0 ; x < 100 ; x ++) {
			System.out.println(Thread.currentThread().getName()+":"+x);
		}	
		return null;
	}
}
public class ExecutorsDemo {
	
	public static void main(String[] args) {
		
		//创建线程池对象
		ExecutorService pool = Executors.newFixedThreadPool(2) ;
		
		//提交任务
		pool.submit(new MyCallable()) ;
		pool.submit(new MyCallable()) ;
		
		//关闭线程池
		pool.shutdown();
	}
}

需求:分别计算每个线程的求和!

public class MyCallable implements Callable<Integer> {
	
	//定义一个变量
	private int number ;

	public MyCallable(int number) {
		this.number = number;
	}
	
	@Override
	public Integer call() throws Exception {
		//定义最终结果变量
		int sum = 0 ;
		for(int x =1 ; x <=number ; x ++) {
			sum +=x ;
		}
		return sum;
	}
}
public class ExecutorsTest {
	
	public static void main(String[] args) throws InterruptedException,
			ExecutionException {
		
		//创建线程池对象
		ExecutorService pool = Executors.newFixedThreadPool(2) ;
		
		//提交任务
		Future<Integer> f1 = pool.submit(new MyCallable(100)) ;
		Future<Integer> f2 = pool.submit(new MyCallable(200)) ;
		
		//V get():获取结果
		Integer i1 = f1.get() ;
		Integer i2 = f2.get() ;
		
		System.out.println(i1);
		System.out.println(i2);
		
		//关闭线程池
		pool.shutdown();
	}
}

猜你喜欢

转载自blog.csdn.net/cangerwjd/article/details/80496166