线程组:表示一个线程的集合。此外,线程组也可以包含其他线程组
线程对象在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();
}
}