多线程(五)线程组线程池

版权声明: https://blog.csdn.net/qq_33278885/article/details/81590274

Java中使用ThreadGroup来表示线程组
它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
默认情况下,所有的线程都属于主线程组。
public final ThreadGroup getThreadGroup()
我们也可以给线程设置分组
Thread(ThreadGroup group, Runnable target, String name) 



public class MyRunnable implements Runnable {
		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) {
		//method();
		method2();
	}

	private static void method2() {
				// 我们如何修改线程所在的组呢?
				// 创建一个线程组
				// 创建其他线程的时候,把其他线程的组指定为我们自己新建线程组
		
		//创建线程组
		ThreadGroup group=new ThreadGroup("新建的线程池");
		MyRunnable m=new MyRunnable();
		//现在我们需要将其他的线程指定为我们自己的线程
		// Thread(ThreadGroup group, Runnable target, String name)
		Thread t1=new Thread(group,m,"线程1");
		Thread t2=new Thread(group,m,"线程1");
		//现在我们检查一下,看这两个线程是那个线程组的
		System.out.println(t1.getThreadGroup().getName());   //新建的线程池
		System.out.println(t2.getThreadGroup().getName());   //新建的线程池
		System.out.println(Thread.currentThread().getThreadGroup().getName());   //main
	}

	private static void method() {
		MyRunnable m=new MyRunnable();
		Thread t1=new Thread(m,"阿杰");
		Thread t2=new Thread(m,"阿冬");
		//现在我想知道这两个线程的线程组是那个应该怎么办?
		// 线程类里面的方法:public final ThreadGroup getThreadGroup()
		ThreadGroup groupone=t1.getThreadGroup();
		ThreadGroup grouptwo=t2.getThreadGroup();
		// 线程组里面的方法:public final String getName()
		System.out.println(groupone.getName());
		System.out.println(grouptwo.getName());
		//得到答案是mian线程,那么主线程的线程池是那个?
		// 通过结果我们知道了:线程默认情况下属于main线程组
		// 通过下面的测试,你应该能够看到,默任情况下,所有的线程都属于同一个组		
		System.out.println(Thread.currentThread().getThreadGroup().getName());
	}

}

线程池
程序启动一个新线程成本是比较高的,
因为它涉及到要与操作系统进行交互。
而使用线程池可以很好的提高性能,
尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。
线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池
 

Runnable对象



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 *  线程池的好处:线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
 *  
 *  如何实现线程的代码呢?
 * 		A:创建一个线程池对象,控制要创建几个线程对象。
 * 			public static ExecutorService newFixedThreadPool(int nThreads)
 * 		B:这种线程池的线程可以执行:
 * 			可以执行Runnable对象或者Callable对象代表的线程
 * 			做一个类实现Runnable接口。
 * 		C:调用如下方法即可
 * 			Future<?> submit(Runnable task)
 *			<T> Future<T> submit(Callable<T> task)
 *		D:我就要结束,可以吗?
 *			可以。
 * */
public class ExecutorsDemo {
public static void main(String[] args) {
	//newFixedThreadPool此方法为静态方法直接用
	//创建线程池pool 并设置其有两个线程
	ExecutorService  pool=Executors.newFixedThreadPool(2);
	//可以执行Runnable对象或者Callable对象代表的线程
	pool.submit(new MyRunnable());
	pool.submit(new MyRunnable());
	//结束
	pool.shutdown();
}
}


public class MyRunnable implements Runnable {

	@Override
	public void run() {
		for(int x=0;x<100;x++ ){
			System.out.println(Thread.currentThread().getName()+"----"+x);
		}
	}

}

Callable对象

Callable好处:
可以有返回值
可以抛出异常
弊端:
代码比较复杂,所以一般不用

实现没有返回值的:

import java.util.concurrent.Callable;

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;
	}
}



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 *  线程池的好处:线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
 *  
 *  如何实现线程的代码呢?
 * 		A:创建一个线程池对象,控制要创建几个线程对象。
 * 			public static ExecutorService newFixedThreadPool(int nThreads)
 * 		B:这种线程池的线程可以执行:
 * 			可以执行Runnable对象或者Callable对象代表的线程
 * 			做一个类实现Callable接口。
 * 		C:调用如下方法即可
 * 			Future<?> submit(Runnable task)
 *			<T> Future<T> submit(Callable<T> task)
 *		D:我就要结束,可以吗?
 *			可以。
 * */
public class ExecutorsDemo {
public static void main(String[] args) {
	//创建线程池
	ExecutorService Pool=Executors.newFixedThreadPool(2);
	//运行线程
	Pool.submit(new MyCallable());
	Pool.submit(new MyCallable());
	//结束
	Pool.shutdown();
}
}

实现有返回值的:

import java.util.concurrent.Callable;
//Callable:是带泛型的接口。
//这里指定的泛型其实是call()方法的返回值类型。
public class MyCallable implements Callable<Integer> {
	private int number;
	MyCallable(Integer num){this.number=num;}
	@Override
	public Integer call() throws Exception {
		Integer num=0;
		for(int x=0;x<=number;x++){
			num+=x;
		}
		return num;
	}
}



import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 *  线程池的好处:线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
 *  
 *  如何实现线程的代码呢?
 * 		A:创建一个线程池对象,控制要创建几个线程对象。
 * 			public static ExecutorService newFixedThreadPool(int nThreads)
 * 		B:这种线程池的线程可以执行:
 * 			可以执行Runnable对象或者Callable对象代表的线程
 * 			做一个类实现Callable接口。
 * 		C:调用如下方法即可
 * 			Future<?> submit(Runnable task)
 *			<T> Future<T> submit(Callable<T> task)
 *		D:我就要结束,可以吗?
 *			可以。
 * */
public class ExecutorsDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
	//需求现在实现一个求和的多线程程式,要求是从1加到这个数本身
	
	
	// 创建线程池对象
			ExecutorService pool = Executors.newFixedThreadPool(2);

			// 可以执行Runnable对象或者Callable对象代表的线程
			Future<Integer> f1 = pool.submit(new MyCallable(100));
			Integer a=f1.get();
			System.out.println(a);
			// 结束
			pool.shutdown();
}
}


匿名内部类线程:
匿名内部类方式使用多线程
new Thread(){代码…}.start();
New Thread(new Runnable(){代码…}).start();

/*
 * 匿名内部类的格式:
 * 		new 类名或者接口名() {
 * 			重写方法;
 * 		};
 * 		本质:是该类或者接口的子类对象。
 */
public class ThreadDemo {
	public static void main(String[] args) {
		// 继承Thread类来实现多线程
		new Thread() {
			public void run() {
				for (int x = 0; x < 100; x++) {
					System.out.println(Thread.currentThread().getName() + ":"
							+ x);
				}
			}
		}.start();

		// 实现Runnable接口来实现多线程
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int x = 0; x < 100; x++) {
					System.out.println(Thread.currentThread().getName() + ":"
							+ x);
				}
			}
		}) {
		}.start();

		// 更有难度的
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int x = 0; x < 100; x++) {
					System.out.println("hello" + ":" + x);
				}
			}
		}) {
			public void run() {
				for (int x = 0; x < 100; x++) {
					System.out.println("world" + ":" + x);
				}
			}
		}.start();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_33278885/article/details/81590274