线程池--面试

Java 中有几种线程池?
考察点:线程池
参考回答:
1、newFixedThreadPool 创建一个指定工作线程数量的线程池。每当提交一个任务就创建一 个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
2、newCachedThreadPool 创建一个可缓存的线程池。这种类型的线程池特点是:
1).工作线程的创建数量几乎没有限制(其实也有限制的,数目为 Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为 1 分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个 工作线程。
3、newSingleThreadExecutor 创建一个单线程化的 Executor,即只创建唯一的工作者线程 来执行任务,如果这个线程异常结束,会有另一个取代它,保证顺序执行(我觉得这点是它的特 色)。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个 线程是活动的 。
4、newScheduleThreadPool 创建一个定长的线程池,而且支持定时的以及周期性的任务执 行,类似于 Timer。(这种线程池原理暂还没完全了解透彻)

11、线程池有什么好处?
考察点:线程池
参考回答:
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能执行。
第三:提高线程的可管理性,线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源, 还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

12、cyclicbarrier 和 countdownlatch 的区别
考察点:线程
参考回答:
CountDownLatch 和 CyclicBarrier 都能够实现线程之间的等待,只不过它们侧重点不同:
CountDownLatch 一般用于某个线程 A 等待若干个其他线程执行完任务之后,它才执行;
而 CyclicBarrier 一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
另外,CountDownLatch 是不能够重用的,而 CyclicBarrier 是可以重用的。

13、启动线程有哪几种方式,线程池有哪几种?
考察点:线程池
参考回答:
①启动线程有如下三种方式:
一、继承 Thread 类创建线程类
(1)定义 Thread 类的子类,并重写该类的 run 方法,该 run 方法的方法体就代表了线程要 完成的任务。因此把 run()方法称为执行体。
(2)创建 Thread 子类的实例,即创建了线程对象。
(3)调用线程对象的 start()方法来启动该线程。
代码:
package com.thread;
public class FirstThreadTest extends Thread{
int i = 0;
//重写 run 方法,run 方法的方法体就是现场执行体
public void run()
{
for(;i<100;i++){
System.out.println(getName()+" “+i);
}
}
public static void main(String[] args)
{
for(int i = 0;i< 100;i++)
{
System.out.println(Thread.currentThread().getName()+” : “+i);
if(i = =20)
{
new FirstThreadTest().start();
new FirstThreadTest().start();
}
}
}
}
上述代码中 Thread.currentThread()方法返回当前正在执行的线程对象。GetName()方法返 回调用该方法的线程的名字。
二、通过 Runnable 接口创建线程类
(1)定义 runnable 接口的实现类,并重写该接口的 run()方法,该 run()方法的方法体同样 是该线程的线程执行体。
(2)创建 Runnable 实现类的实例,并依此实例作为 Thread 的 target 来创建 Thread 对象, 该 Thread 对象才是真正的线程对象。
(3)调用线程对象的 start()方法来启动该线程。
代码:
package com.thread;
public class RunnableThreadTest implements Runnable
{
private int i;
public void run()
{
for(i = 0;i <100;i++)
{
System.out.println(Thread.currentThread().getName()+” “+i);
}
}
public static void main(String[] args)
{
for(int i = 0;i < 100;i++)
{
System.out.println(Thread.currentThread().getName()+” “+i);
if(i= =20)
{
RunnableThreadTest rtt = new RunnableThreadTest();
new Thread(rtt,“新线程 1”).start();
new Thread(rtt,“新线程 2”).start();
}
}
}
}
三、通过 Callable 和 Future 创建线程
(1)创建 Callable 接口的实现类,并实现 call()方法,该 call()方法将作为线程执行体, 并且有返回值。
(2)创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call()方法的返回值。
(3)使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
(4)调用 FutureTask 对象的 get()方法来获得子线程执行结束后的返回值
代码:
package com.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableThreadTest implements Callable
{
public static void main(String[] args)
{
CallableThreadTest ctt = new CallableThreadTest();
FutureTask ft = new FutureTask<>(ctt);
for(int i = 0;i < 100;i++)
{
System.out.println(Thread.currentThread().getName()+” 的循环变量 i 的值
“+i);
if(i==20)
{
new Thread(ft,“有返回值的线程”).start();
}
}
try
{
System.out.println(“子线程的返回值:”+ft.get());
} catch (InterruptedException e)
{
e.printStackTrace();
} catch (ExecutionException e)
{
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception
{
int i = 0;
for(;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+” "+i);
}
return i;
}
}
②线程池的种类有:
Java 通过 Executors 提供四种线程池,分别为:
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲 线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值