Javaday17多线程高级

线程通信

在Java中一共有四种方法支持同
步,其中前三个是同步方法,一个是管道方法。
(1)Object的wait() / notify()方法 (2)LockCondition的await() / signal()方法 (3)
BlockingQueue阻塞队列方法 (4)PipedInputStream / PipedOutputStream
比较synchronized和Lock
1.synchronized:从jdk1.0就开始使用的同步方法-称为隐式同步
synchronized(锁对象){//获取锁 我们将锁还可以称为锁旗舰或者监听器
同步的代码
}//释放锁
2.Lock:从jdk1.5开始使用的同步方法-称为显示同步
原理:Lock本身是接口,要通过他的子类创建对象干活儿
常用子类:ReentrantLock
使用过程:
首先调用lock()方法获取锁
进行同步的代码块儿
使用unlock()方法释放锁
使用的场景:
当进行多生产者多消费者的功能时,使用Lock,其他的都使用synchronized
使用效率:Lock高于synchronized
比较Object多wait,notify和Condition的await,signal
唤醒等待机制
Object类中几个方法如下:
wait()
等待,让当前的线程,释放自己持有的指定的锁标记,进入到等待队列。
等待队列中的线程,不参与CPU时间⽚的争抢,也不参与锁标记的争抢。
notify()
通知、唤醒。唤醒等待队列中,⼀个等待这个锁标记的随机的线程。
被唤醒的线程,进⼊到锁池,开始争抢锁标记。
notifyAll()
通知、唤醒。唤醒等待队列中,所有的等待这个锁标记的线程。
被唤醒的线程,进⼊到锁池,开始争抢锁标记。
waitsleep的区别
sleep()方法,在休眠时间结束后,会自动的被唤醒。 而wait()进入到的阻塞态,需要被
notify/notifyAll手动唤醒。
wait()会释放自己持有的指定的锁标记,进入到阻塞态。sleep()进入到阻塞态的时候,不
会释放自己持有的锁标记。
注意事项
无论是wait()方法,还是notity()/notifyAll()⽅法,在使用的时候要注意,⼀定要是自己持
有的锁标记,才可以做这个操作。否则会出现 IllegalMonitorStateException 异常。
死锁
出现的情况有两种
所有的线程处于等待状态
大家都处于等待状态,没有人获取cpu使用
锁之间进行嵌套调用
多个线程, 同时持有对方需要的锁标记, 等待对方释放自己需要的锁标记。此时就是出现死
锁。 线程之间彼此持有对方需要的锁标记, 而不进行释放, 都在等待。
线程休眠, 就是让当前的线程休眠指定的时间。 休眠的线程进入到阻塞状态, 直到休眠结
束。 阻塞的线程, 不参与CPU时间片的争抢。
注: 线程休眠的时间单位是毫秒。
将一个线程中的任务, 合并入到另外一个线程中执行, 此时, 合并进来的线程有限执行。
类似于: 插队。
注意:优先级只比main线程的高.对其他的线程没有影响
设置线程的优先级, 可以决定这个线程能够抢到CPU时间片的概率。 线程的优先级范围在
[1, 10], 默认的优先级是5。 数值越高, 优先级越高。 但是要注意, 并不是优先级高的线程
一定能抢到CPU时间片, 也不是优先级的线程一定抢不到CPU时间片。 线程的优先级只是决
定了这个线程能够抢到CPU时间片的概率。 即便是优先级最低的线程, 依然可以抢到CPU时
间片。
守护线程, 又叫后台线程。 是一个运行在后台, 并且会和前台线程争抢CPU时间片的线程。
守护线程依然会和前台线程争抢CPU时间片, 实现并发的任务。
在一个进程中, 如果所有的前台线程都结束了, 后台线程即便任务没有执行结束, 也会
自动结束。
线程池, 其实就是一个容器, 里面存储了若干个线程。
使用线程池, 最主要是解决线程复用的问题。 之前使用线程的时候, 当我们需要使用一个线
程时, 实例化了一个新的线程。 当这个线程使用结束后, 对这个线程进行销毁。 对于需求
实现来说是没有问题的, 但是如果频繁的进行线程的开辟和销毁, 其实对于CPU来说, 是一
种负荷, 所以要尽量的优化这一点
可以使用复用机制解决这个问题。 当我们需要使用到一个线程的时候, 不是直接实例化, 而
是先去线程池中查找是否有闲置的线程可以使用。 如果有, 直接拿来使用; 如果没有, 再
实例化一个新的线程。 并且, 当这个线程使用结束后, 并不是马上销毁, 而是将其放入到
线程池中, 以便下次继续使用。
线程池的开辟
int corePoolSize
核心线程的数量
int maximunPoolSize
线程池最大容量(包含了核心线程和临时线
程)
long keepAliveTime
临时线程可以空闲的时间
TimeUnit unit
临时线程保持存活的时间单位
BlockingQueue<Runnable>
workQueue
任务等待队列
RejectedExecutionHandler handler
拒绝访问策略
int corePoolSize
核心线程的数量
int maximunPoolSize
线程池最大容量(包含了核心线程和临时线
程)
long keepAliveTime
临时线程可以空闲的时间
TimeUnit unit
临时线程保持存活的时间单位
BlockingQueue<Runnable>
workQueue
任务等待队列
RejectedExecutionHandler handler
拒绝访问策略
execute(Runnable
runnable)
将任务提交给线程池, 由线程池分配线程来并发处理。
shutdown()
向线程池发送一个停止信号,这个操作并不会停止线程池中的线
程,而是在线程池中所有的任务都执行结束后,结束线程和线程
池。
shutdownNow()
立即停止线程池中的所有的线程和线程池。
线程池的开辟, 除了可以使用构造方法进行实例化, 还可以通过Executors工具类进行获
取。 实际应用中, 大部分的场景下, 可以不用前面的构造方法进行线程池的实例化, 而是
用Executors工具类中的方法进行获取。
Executors.newSingleThreadExecutor()
核心线程1
最大线程1
等待队列容量 Integer.MAX_VALUE
Executors.newCachedThreadPool()
核心线程0
最大线程Integer.MAX_VALUE
闲置时间 60
Executors.newFixedThreadPool(int size)
核心线程size
最大线程 size
等待队列容量 Integer.MAX_VALUE
submit()
向线程池中添加任务
shutdown()
停止线程池
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值