Runnable是线程吗?
Runnable不是线程,Thread才是。比如单一线程池Executor会在内部创建一个Thread,这个Thread会从一个任务队列中取出用户提交的任务并执行,如果在执行的过程中出现异常,Executor会自动启动新线程继续执行。
Thread的优缺点?
优点:通过new Thread()创建线程API简单易于使用,结构清晰,对于执行单一的一次性任务十分便利。
缺点:
1. 每次new Thread新建对象性能差
2. 没有线程管理者,可能会无限制新建线程,互相之间竞争,极有可能占用过多的系统资源导致OOM
3. 缺乏更多功能,比如定时、定期、并发数控制等功能
线程池的优点?
1. 缓存线程,进行池化,可实现对线程的重复利用,避免重复创建和销毁线程所带来的性能开销。
2. 当任务在执行的过程中如出现异常,会重新创建线程继续完成任务。
3. 任务按照指定的规则执行,线程池通过队列的形式来接收任务,通过空闲线程来逐一取出任务调度。
4. 可定制拒绝策略,即任务队列已满时,后来的任务可拒绝处理。
Thread和Executor的区别?
(为什么刀要分为很多种,比如菜刀、砍刀、杀猪刀?答案是功能不同,需要针对性处理)。
两者最大的区别应该是Executor更像是一个管理者和Thread的集合,而Thread只是一个任务的执行者。
Executor线程池的使用
public class TestExecutor
{
public static void main(String[] args)
{
// testCachedThreadPool();
// testFixedThreadPool();
// testSingleThreadExecutor();
// testScheduledThreadPool();
// testSingleThreadScheduledExecutor();
}
/**
* 可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.
*/
static void testCachedThreadPool()
{
ExecutorService es = Executors.newCachedThreadPool();
for(int i = 0 ; i < 10 ; i++){
final int index = i;
es.execute(new Runnable() {
@Override
public void run()
{
System.out.println("index = " + index);
}
});
}
}
/**
* 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
*/
static void testFixedThreadPool()
{
ExecutorService es = Executors.newFixedThreadPool(3);
for(int i = 0 ; i < 10 ; i++){
final int index = i;
es.execute(new Runnable() {
@Override
public void run()
{
System.out.println("index = " + index);
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
}
}
/**
* 一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
*/
static void testSingleThreadExecutor()
{
ExecutorService es = Executors.newSingleThreadExecutor();
for(int i=0;i<10;i++){
final int index = i;
es.execute(new Runnable() {
@Override
public void run()
{
System.out.println("index = "+index);
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
}
}
/**
* 定长线程池,支持定时及周期性任务执行
*/
static void testScheduledThreadPool()
{
ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
//延迟3秒钟
ses.schedule(new Runnable() {
@Override
public void run()
{
System.out.println("delay 3s");
}
}, 3, TimeUnit.SECONDS);
//延迟3秒钟,以固定频率5s定时执行
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run()
{
System.out.println("run ...");
}
}, 3, 5, TimeUnit.SECONDS);
}
/**
* 单线程化的线程池,支持定时及周期性任务执行
* 适用于非批量操作,如app的安装、卸载等
*/
static void testSingleThreadScheduledExecutor()
{
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
//延迟3秒钟
ses.schedule(new Runnable() {
@Override
public void run()
{
System.out.println("delay 3s");
}
}, 3, TimeUnit.SECONDS);
//延迟3秒钟,以固定频率5s定时执行
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run()
{
System.out.println("run ... ");
}
}, 3, 5, TimeUnit.SECONDS);
}
}