线程笔记

这一阵读了《JAVA并发编程实战》,写demo,看资料,记了一堆乱七八糟的东西。记下笔记,有空看看,免得遗忘

线程状态

状态 简易说明 进入方法 备注
新建状态(New) 刚刚创建,没开始执行 对象new之后
就绪状态(Runnable) 已经准备好,随时可以调用 thread.start()之后,线程线程执行之前New
或者,阻塞接触之后
运行状态(Running) 执行中 就绪的线程获取CPU运行权限 只能【就绪】->【运行】
阻塞状态(Blocked) 放弃CPU执行 wait()(等待)、synchronized锁(同步)、sleep或join()(切换)之后 IO也会造成阻塞(read(),write())
死亡状态(Dead) 执行完毕或者异常退出


参考:http://www.cnblogs.com/skywang12345/p/3479024.html


线程状态改变方法

名称 简易说明 备注
wait() 线程等待,线程进入等待阻塞状态,等待到时间或者被唤醒 1,t1.wait()不是使t1等待,可是执行此语句的线程等待
2,会释放所有同步锁
notify()和notifyAll() 线程唤醒,唤醒单个/全部的等待线程 t1.不是唤醒自身,而是等待中的线程
yield() 线程让步,线程重新进入就绪状态 不会释放锁
sleep() 限时阻塞,进入阻塞一定时间后,自动进入就绪状态 不会释放锁
join() t1.join(),让当前线程阻塞,直到t1线程执行完成后,进入就绪状态 本质是主线程不断wait()
interrupt() 线程中断,设置线程的中断标志,线程执行到阻塞时,清除标记并抛出InterruptedException的异常 1,当前线程以外使用interrupt(),会检测权限

注:由于notify(), wait()依赖于对象自身的同步锁,所以这些方法存在于Object对象中


加锁方法

名称 简易说明 用法 备注
synchronized 同步方法或代码块 synchronized 方法(){
...
}
synchronized(锁对象){
...
}
依赖于对象:不明确锁对象时,锁对象是类的实例自身
volatile 修饰变量,保证每次直接读值 volatile 变量类型 变量 常用于flg用的共享成员的
Lock 显示的加锁方法 Lock lock = new ReentrantLock();
......
try {
lock.lock();
.....
} finally {
lock.unlock();
}
显式的创建,有tryLock()等方法扩展
ReentrantLock:独占锁,公平锁。
ReadWriteLock:读写锁:读取锁是共享锁,写入锁是独占锁。
CountDownLatch 闭锁:计数,阻塞等待至计数为零 new CountDownLatch(int 等待数) countDown():计数减少
await():阻塞等待值计数为零
CyclicBarrier 栅栏:阻塞的线程达到一定数量之后,一起执行 new CyclicBarrier(int 等待数) await():阻塞等待,直到阻塞的线程达到一定数量
Semaphore 信号量:有N个资源,如获取时无资源则阻塞等待 new Semaphore(int 初始资源数) relase():释放/增加资源
acquire():获取,减少资源

线程内任务载体(全是接口):

接口名 父类 简易说明 方法
Runnable 最基本的线程载体 void run()包含执行内容,无参数返回值
TimerTask Runnable Timer用定时的线程 void run()包含执行内容,无参数返回值
boolean cancel()自身取消用
Callable 带返回值得线程载体 V call()包含执行内容,并返回返回值

线程载体:

类名/接口名 载体类型 简易说明 创建 方法
Thread(类) Runnable 线程(Runnable的实现) new Thread(Runnable target) void start()启动线程
String getName()返回该线程的名称
void setName(String name)设置线程名称
int getPriority()返回线程的优先级。
void setPriority(int newPriority)更改线程的优先级
boolean isDaemon()该线程是否为守护线程
void setDaemon(boolean on)将该线程标记为守护线程或用户线程
void sleep(long millis) 线程休眠
void interrupt()中断线程
void yield()线程让步,切换线程
void join()使得调用线程等待,直到此该线程终止
Timer(类) TimerTask(Runnable子类) 多线程,定时/延时启动 new Timer()

void schedule(TimerTask task, long delay, long period)追加并启动线程(按照上次的结束时间循环)
scheduleAtFixedRate(TimerTask task, long delay, long period)追加并启动线程(按照上次的开始时间循环)
void cancel()线程取消
int purge()移除所有已取消的任务
Executor(接口) Runnable 多线程线程池 Executors.newFixedThreadPool(int num)限制线程数的线程池
Executors.newCachedThreadPool()可缓存线程池
Executors.newScheduledThreadPool(int num)定长线程池,类似timer
Executors.newSingleThreadExecutor()单线程线程池,唯一执行
void execute(Runnable command)追加执行线程
ExecutorService(接口) Runnable
Callable
多线程线程池管理(Executor的扩展) 同上 Future submit(Callable task) 提交带Callable线程
Future<?> submit(Runnable task)提交Runnable线程
List<Future> invokeAll(Collection<? extends Callable> tasks, long timeout, TimeUnit unit) 批量提交Callable线程
void shutdown()关闭
Future(接口) 承载线程状态 线程的状态管理对象 使用ExecutorService的相关方法的返回值 V get()取得执行结果,线程未执行完毕时,阻塞
V get(long timeout, TimeUnit unit)限时取得结果,超时抛异常
boolean cancel(boolean mayInterruptIfRunning)取消线程
boolean isCancelled()判断是否取消
boolean isDone()判断是否执行完成
FutureTask(类) Future + Runnable或Callable 线程和其管理对象的结合体 FutureTask(Callable callable)
FutureTask(Runnable runnable, V result)
用时有线程和future的方法
CompletionService(接口) Executor 队列的方式管理多线程 new ExecutorCompletionService(Executor executor)
ExecutorCompletionService是其接口的实现
Future submit(Callable task)提交Callable线程
Future submit(Runnable task, V result)提交Runnable线程
Future take()取得结果
Future poll()取得并删除结果
Future poll(long timeout, TimeUnit unit)限时取得并删除结果

注:对于Thread的start()和run():

start():它的作用是启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。
run():run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
也就是说start()是启动线程,在新线程执行run()的内容;run()是执行名为run()的方法


线程池的实现:

  1. 线程池的实现是ThreadPoolExecutor(->AbstractExecutorService->ExecutorService->Executor)。
  2. Executors.newXXX等方法,实际上都是new ThreadPoolExecutor。(java8新增的newWorkStealingPool使用另一种实现ForkJoinPool,可拆分大任务)
  3. ThreadPoolExecutor的初始化参数如下:
名称 类型 说明 备注
corePoolSize int 基本大小 不推荐设0不要太小
maximumPoolSize int 最大大小 不要太大
keepAliveTime long 超时时间 当将allowCoreThreadTimeOut设置为true时对corePoolSize生效
unit TimeUnit keepAliveTime的单位 如TimeUnit.SECONDS
workQueue BlockingQueue 任务队列 一般使用LinkedBlockingQueue或者SynchronousQueue
threadFactory ThreadFactory 线程工厂 提供创建新线程的功能
handler RejectedExecutionHandler 拒绝策略(饱和策略) 线程池满时的处理方法:
AbortPolicy
DiscardPolicy
DiscardOldestPolicy
CallerRunsPolicy

线程锁:

名词 简易说明 例子 备注
死锁 自己占有他人请求资源的时候,去请求他人的资源 ①程序1,锁住资源A
②程序2,锁住资源B
③程序1,请求资源B,阻塞
④程序2,请求资源A,阻塞
相互出在阻塞状态,简单可记为A->B,B->A
活锁 执行状态和顺序一定的情况下,一旦一次失败,导致程序不断重试 ①程序1,锁住资源A
②程序2,锁住资源B
③程序1,请求资源B,请求失败
④程序2,请求资源A,请求失败
⑤程序1,释放资源A,重新开始
⑥程序2,释放资源B,重新开始
之后从①开始,循环
不阻塞,不断执行,不断失败重试
饥饿 由于不公平锁,优先级等问题,导致一直无法取到资源 ①程序1,程序2争夺资源资源A,程序2胜出
②程序1,程序3争夺资源资源A,程序3胜出
③程序1,程序4争夺资源资源A,程序4胜出
...
不阻塞,不重复,但某些程序无法执行
posted @ 2018-04-24 17:41  常烦常乐  阅读(110)  评论(0编辑  收藏  举报