一:2個生產者、10個消費者洒嗤,自己定義一個容器粗俱,實現put、get方法wait notify+synchroized
- synchronized鎖了這個對象锥忿,相當于實現了count變量的原子性牛郑,操作系統里面pv操作講過
- wait方法不僅僅是進入阻塞隊列阻塞,而且讓出鎖
- 注意1:條件是while不是if ????? 2:notifyall不是notify
import java.util.LinkedList;
public class MyContainer<T> {
private LinkedList<T> lists = new LinkedList<T>();
private static final int MAX = 10;
private static int count = 0;
private synchronized void put(T t){
while(count==MAX){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lists.add(t);
++count;
System.out.println(Thread.currentThread().getName()+"放入一個敬鬓。 count="+count);
this.notifyAll();
}
private synchronized T get(){
while(count==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T temp = lists.get(lists.size()-1);
--count;
System.out.println(Thread.currentThread().getName()+"拿走一個淹朋。 count="+count);
this.notifyAll();
return temp;
}
public static void main(String[] args) {
MyContainer<Object> container = new MyContainer<Object>();
//開啟生產者
new Thread(()->container.put(new Object()),"thread1").start();
new Thread(()->container.put(new Object()),"thread2").start();
for(int i=0;i<10;i++){
new Thread(()->container.get(),"consumer"+i).start();
}
}
}
二:2個生產者、10個消費者钉答,自己定義一個容器础芍,實現put、get方法Condition+Renntrantlock数尿。
比第一種方法有啥優(yōu)點:
- 更容易處理異常仑性。synchronized中間遇到異常會直接釋放鎖,線程會直接結束右蹦,假設一個線程只執(zhí)行了一半诊杆,那就可能產生臟數據。使用Renntrantlock方便控制(lock.lock lock.unlock 碰到異常還可以自己先處理)何陆。
- 效率更好刽辙。Condition相當于設置了兩個等待隊列,可以單獨喚醒所有的消費者甲献,或者單獨喚醒所有的生產者宰缤。而第一種方式是喚醒所有的線程。
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyContainer2<T> {
private LinkedList<T> lists = new LinkedList<T>();
private static final int MAX = 10;
private static int count = 0;
private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();
private Condition consumer = lock.newCondition();
private void put(T t){
try {
lock.lock();
while(lists.size()==MAX) {
producer.await();
}
System.out.println(Thread.currentThread().getName()+"放入一個");
lists.add(t);
count++;
consumer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private T get(){
T temp = null;
try{
lock.lock();
while(lists.size()==0){
consumer.await();
}
System.out.println(Thread.currentThread().getName()+"取走一個");
count--;
temp = lists.poll();
producer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return temp;
}
public static void main(String[] args) {
MyContainer2<Object> container = new MyContainer2<Object>();
//開啟生產者
new Thread(()->container.put(new Object()),"thread1").start();
new Thread(()->container.put(new Object()),"thread2").start();
for(int i=0;i<10;i++){
new Thread(()->container.get(),"consumer"+i).start();
}
}
}
111