线程组和线程池的理解

上面我们了解了线程,接下来我们再来看看线程组

线程组:

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

下面来看个例子:

package com.westos.Thread4;
 
public  class MyThread implements Runnable{
 
public void run() {
for(int x=0;x<10;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Thread4;
 
public class ThreadDome {
 
public static void main(String[] args) {

method1();
// method2();
}
 
//方式2:
private static void method2() {
//创建资源类对象
MyThread my=new MyThread();
//创建一个新的线程组对象
ThreadGroup tg=new ThreadGroup("牛鼻的线程组");
//创建Thread类对象,新的一种Thread类构造方法
//Thread(ThreadGroup group, Runnable target, String name)
Thread t1=new Thread(tg,my,"刘备");
Thread t2=new Thread(tg,my,"张飞");

//输出线程组的名字
System.out.println(t1.getThreadGroup().getName());
System.out.println(t2.getThreadGroup().getName());
System.out.println(Thread.currentThread().getName());
}
 
//方式1:
private static void method1() {
//创建资源类对象
MyThread mt=new MyThread();
//创建线程对象
Thread t1=new Thread(mt,"线程1");
Thread t2=new Thread(mt,"线程2");
//调用Thread类中的getThreadGroup()方法,返回的是线程组
ThreadGroup tg1 = t1.getThreadGroup();
ThreadGroup tg2 = t2.getThreadGroup();

//然后输出线程组的名字
System.out.println(tg1.getName());
System.out.println(tg2.getName());
System.out.println(Thread.currentThread().getName());
}
}
运行结果:
main
main
main
-------------
牛鼻的线程组
牛鼻的线程组
main

 

 

上面我们了解了线程组接下来我们再来看看线程池:

线程池: 可以说是线程的容器,当线程在start()方法执行后java虚拟机运行完run方法后,线程就会被当做垃圾一样等待回收掉,但是线程池中的线程被执行后,他会重新回到线程池中等待被重新利用,这是线程池的好处

Executors: 一种工厂类

 

方法:

  和线程池的创建有关系

  public static ExecutorService newFixedThreadPool(int nThreads)

  创建一个可重用固定线程数的线程池

 

让我们先来看看线程池的引入

例如:

package com.westos.Executor;
 
public class MyThread implements Runnable{
 
@Override
public void run() {

for(int x=0;x<7;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Executor;
/**
 * Executors类是一个有线程池有关的工厂类
 */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class ExecutorDome {
 
public static void main(String[] args) {

//该方法可以确定线程池内线程的数量,返回的是一个线程池
//newFixedThreadPool(int nThreads, ThreadFactory threadFactory): 创建一个可重用固定线程数的线程池
ExecutorService ThreadGroupTool = Executors.newFixedThreadPool(2);

//提交Runnable接口的方法或者callable接口
ThreadGroupTool.submit(new MyThread());
ThreadGroupTool.submit(new MyThread());

//关闭线程池
//shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
ThreadGroupTool.shutdown();
}
}
 
运行结果:
pool-1-thread-2:0
pool-1-thread-1:0
pool-1-thread-2:1
pool-1-thread-1:1
pool-1-thread-2:2
pool-1-thread-1:2
pool-1-thread-2:3
pool-1-thread-1:3
pool-1-thread-2:4
pool-1-thread-1:4
pool-1-thread-2:5
pool-1-thread-1:5
pool-1-thread-1:6
pool-1-thread-2:6

 

从上面的运行结果可以看出pool代表的就是线程池,后面跟的1就是线程池的数量,再后面的thread就是线程池中的线程了

 

我们在之前学习过了多线程的实现方式有两种分别是:继承Thread类和实现Runnable接口,接下来让我们再看看实现多线程的第三种方式:线程池中实现Callable接口,在面试的时候,当考官询问我们关于实现多线程的方式时,我们回答出前面学习的两种就可以了,第三种如果能记得,那就更好了,可以为你加分的

 

现在让我们看看多线程的第三种实现方式:

package com.westos.Executor2;
 
import java.util.concurrent.Callable;
 
public class MyCallable implements Callable{
 
@Override
public Object call() throws Exception {
for(int x=0;x<7;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
return null;
}
 

}

 

 

package com.westos.Executor2;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
/**
 * 实现多线程的第三种方式
 * 前提得自定义类去实现Callable接口
 */
public class ExecutorDome {
 
public static void main(String[] args) {

//调用Executor的返回线程池的方法
ExecutorService pool = Executors.newFixedThreadPool(2);

//提交 Callable接口的方法 
pool.submit(new MyCallable());
pool.submit(new MyCallable());

//关闭线程池
pool.shutdown();
}
}
运行结果:
pool-1-thread-1:0
pool-1-thread-1:1
pool-1-thread-1:2
pool-1-thread-1:3
pool-1-thread-1:4
pool-1-thread-1:5
pool-1-thread-1:6
pool-1-thread-2:0
pool-1-thread-2:1
pool-1-thread-2:2
pool-1-thread-2:3
pool-1-thread-2:4
pool-1-thread-2:5
pool-1-thread-2:6

 

可以看出依旧可以运行出多线程之间的特点

 

当我们想要实现线程之间的和运算应该怎么做呢?

package com.westos.Executors;
 
import java.util.concurrent.Callable;
 
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=0;x<=number;x++) {
sum+=x;
}
//因为这里需要返回线程之间的和的值,所以需要将null改为sum
return sum;
}
 
}

 

 

package com.westos.Executors;
 
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class ExecutorsDome {
 
public static void main(String[] args) throws InterruptedException, ExecutionException {

//调用方法返回创建线程池
//ExecutorService:可以执行异步任务
ExecutorService pool = Executors.newFixedThreadPool(2);

//提交Callable方法,返回的是future接口
//Future 表示异步计算的结果
Future<Integer> f1 = pool.submit(new MyCallable(100));
Future<Integer> f2 = pool.submit(new MyCallable(200));

//get()  如有必要,等待计算完成,然后获取其结果。
Integer i1 = f1.get();
Integer i2 = f2.get();

System.out.println(i1);
System.out.println(i2);
//关闭线程池
pool.shutdown();
}
}
运行结果:
5050
20100

猜你喜欢

转载自blog.csdn.net/j_better/article/details/80526878
今日推荐