线程

实现线程方式 继承Thread类 和 实现 Runnable接口

调用start执行线程、调用run 会在主线程执行

线程五个状态:新建、就绪、运行、阻塞(等待)、结束

等待分为:有限期等待和无限期等待
有时间声明的属有限期等待、没有时间的要通过notify notifyall唤醒

Thread.sleep()

monitor 持有锁

Object.wait()

monitor 释放锁

Thread.interrupt()

Thread.isInterrupt()

join 等待子线程执行完毕

A线程中等待B线程执行完毕 使用方式:b.join()
在线程池中join方法不适用
join()似乎要在thread.start()后才能有效,而线程池则直接用threadPool.execute(runnable or thread),用join()无效。

volatile关键字:轻量级线程并发行变量可见、数据在CPU RAM中直接读取、并维护更新

yield 让出线程给 同等级线程执行时间

线程四种

1、单线程

1
2
3
4
5
6
7
8
9
10
11
/**
* 创建一个单线程的线程池.
* 这个线程池只有一个线程在工程,也就是相当于单线程串行执行所有任务.
* 如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它.
* 此线程池保证所有任务的执行顺序都会按照提交的顺序执行.
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

2、固定数目线程

1
2
3
4
5
6
7
8
9
10
11
/**
* 创建固定大小的线程池.
* 每次提交一个任务就会创建一个线程,直到线程达到线程池的最大大小.
* 线程池的大小一旦达到最大值就会保持不变,如果某个线程因为异常而技术,
* 那么该线程池会补充一个新的线程.
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

3、缓存线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


/**
*创建一个可缓存的线程池.
*如果线程池的大小超过了处理任务所需要的线程,
*那么就会回收部分空闲(60秒不执行任务)的线程,
*当任务数增加时,此线程池又可以智能的添加新线程来处理任务.
*此线程池不会对线程池大小做限制,
*线程池大小完全依赖与操作系统(或者说JVM)能够创建的最大线程数.
**/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

4、定时线程

1
2
3
4
5
6
7

/**
*创建一个大小无限的线程池.此线程池支持定时以及周期性执行任务的需求.
*/
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}

关于线程:

  • 1.线程并不是越多越好.切换线程的开销很大、如果线程太多、切换时间远大于执行时间就得不偿失了
  • 2.线程该用才用.跟事物一样.不该用不要用.否则反而降低性能
  • 3.线程池数量 差不多是 CPU核数 * 2
  • 4.阿里编码规范已不推荐使用ExcutorService方法使用线程

{———-}

1
2
3
4
5
6
7
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

代码地址:https://gitee.com/none_heart/xingchen/tree/master/excutor

void execute()

Future sumbit()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


/**
* 线程池管理的工具类,封装类
* @author ThinkPad
* 线程池的管理 ,通过java 中的api实现管理
* 采用conncurrent框架: 非常成熟的并发框架 ,特别在匿名线程管理非常优秀的
*
*/
public class ThreadManager {
//通过ThreadPoolExecutor的代理类来对线程池的管理
private static ThreadPollProxy mThreadPollProxy;
//单列对象
public static ThreadPollProxy getThreadPollProxy(){
synchronized (ThreadPollProxy.class) {
if(mThreadPollProxy==null){
mThreadPollProxy=new ThreadPollProxy(3,6,1000);
}
}
return mThreadPollProxy;
}
//通过ThreadPoolExecutor的代理类来对线程池的管理
public static class ThreadPollProxy{
private ThreadPoolExecutor poolExecutor;//线程池执行者 ,java内部通过该api实现对线程池管理
private int corePoolSize;
private int maximumPoolSize;
private long keepAliveTime;

public ThreadPollProxy(int corePoolSize,int maximumPoolSize,long keepAliveTime){
this.corePoolSize=corePoolSize;
this.maximumPoolSize=maximumPoolSize;
this.keepAliveTime=keepAliveTime;
}
//对外提供一个执行任务的方法
public void execute(Runnable r){
if(poolExecutor==null||poolExecutor.isShutdown()){
poolExecutor=new ThreadPoolExecutor(
//核心线程数量
corePoolSize,
//最大线程数量
maximumPoolSize,
//当线程空闲时,保持活跃的时间
keepAliveTime,
//时间单元 ,毫秒级
TimeUnit.MILLISECONDS,
//线程任务队列
new LinkedBlockingQueue<Runnable>(),
//创建线程的工厂
Executors.defaultThreadFactory());
}
poolExecutor.execute(r);
}
}
}