1.wait,nofity管理并发
2.Condition实现线程间通讯
3.Semaphore管理多线程竞争
在生产者消费者问题观察wait和notify(//TODO)
1.均要放在synchronized作用域中
2.执行wait,释放synchronized所关联的锁,进入阻塞状态,无法再次主动进入可执行状态。
3.执行notify,通知因调用wait方法而等待锁的线程,如多个线程等待,任意一个被唤醒。
4.notifyAll会唤醒因wait进入阻塞状态的线程,但是他们没得到锁,会进行竞争,得到锁的继续执行,在它释放后,其他的继续竞争。
当仓库满,wait生产中线程,notify消费者线程
当仓库控,notify生产中线程,wait消费者线程
示例:商品类,生产者类,消费者类,创建一个队列当货架。
通过Condition实现线程间通讯(//TODO)
当线程A调用Condition的await方法后,释放对应的对象锁,自己进入阻塞状态,等待被其他线程唤醒。
线程B得到锁资源后,开始执行业务,完成后,调用Condition的signal方法唤醒A,恢复执行。
基于Object类的wait,notify,notifyAll方法,只能建立一个阻塞队列,通过Condition类可以在不同的线程里创建多个阻塞队列。
Semaphore管理多线程竞争
多个线程竞争数量相对少的资源。(比如100个线程需要连接到同一个数据库,但是同时最多提供10个连接)
Semaphore类是个计数信号量。
构造函数参数(int permits,boolean fair),permits代表初始化可用的资源数目,fair代表是否为公平锁。
用acquire申请资源,release方法释放资源.(acquire时候发现数目上限,自动进入阻塞队列,当有空闲资源时,自动获取,不需要额外操作)
import java.util.concurrent.Semaphore;
class ConnectionProvide{
public void provide(){
//TODO
}
}
class HandleUserThread extends Thread{
private Semaphore semaphore;
private String threadName;
private ConnectionProvide provider;
public HandleUserThread(String threadName, Semaphore semaphore, ConnectionProvide provider){
this.semaphore = semaphore;
this.threadName = threadName;
this.provider = provider;
}
public void run(){
if(semaphore.availablePermits() > 0){
System.out.println(threadName + "start.apply the connection");
}else {
System.out.println(threadName + "start.no available connection");
}
try {
semaphore.acquire();
provider.provide();
Thread.sleep(1000);
System.out.println(threadName + "get connection");
//用数据库的链接
semaphore.release();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class SemaphoreDemo {
public static void main(String[] args){
ConnectionProvide provider = new ConnectionProvide();
Semaphore semaphore = new Semaphore(2,true);
for (int i = 0; i < 5; ++i){
new HandleUserThread(Integer.valueOf(i).toString(),semaphore,provider).start();
}
}
}
输出
0start.apply the connection
1start.apply the connection
2start.no available connection
3start.no available connection
4start.no available connection
1get connection
0get connection
3get connection
2get connection
4get connection