《原神攻略》胡桃培養建議
阿新 • • 發佈:2021-06-19
一個容器,兩個方法put()和get()方法
兩個生產者,十個消費者,生產者生產達到MAX數量時阻塞,消費者消費到MAX數量為0時阻塞。
使用CAS加鎖
public class TestReetrantLock1 { private static LinkedList<Object> list=new LinkedList<Object>(); private int MAX=10; private int count; private ReentrantLock lock=new ReentrantLock(); privateCondition prod=lock.newCondition(); private Condition cons=lock.newCondition(); public void put(Object t) { try { lock.lock(); while (list.size()==MAX){ System.out.println("容器中已經放滿,停止生產"); prod.await(); } System.out.println("容器開始存放"); list.add(t); ++count; System.out.println("容器現在存放"+count); cons.signalAll();//通知消費者執行緒消費 } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public synchronized Object get(){ Object t=null; try{ lock.lock(); while (list.size()==0){ System.out.println("容器中已經空了,停止消費"); cons.await(); } System.out.println("容器開始消費"); t=list.removeFirst(); count--; System.out.println("容器現在剩餘"+count); prod.signalAll(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } return t; } public static void main(String[] args) { TestReetrantLock t=new TestReetrantLock(); //消費者 for (int i = 0; i <10 ; i++) { new Thread(()->{ for (int j = 0; j <5 ; j++) { t.get(); } }).start(); } try{ TimeUnit.SECONDS.sleep(1); }catch (Exception e){ e.printStackTrace(); } //生產者 for (int i = 0; i <2 ; i++) { new Thread(new Runnable() { @Override public void run() { for (int j = 0; j <25 ; j++) { t.put(Thread.currentThread().getName()); } } }).start(); } } }
使用synchronized加鎖
public class TestReetrantLock { private static LinkedList<Object> list=new LinkedList<Object>(); private int MAX=10; private int count; public synchronized void put(Object t) {//加鎖因為++count非原子操作 while (list.size() == MAX){//注意此處為什麼是while而不是if? try { System.out.println("容器中已經放滿,停止生產"); this.wait(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("容器開始存放"); list.add(t); ++count; System.out.println("容器現在存放"+count); this.notifyAll();//喚醒其它執行緒 } public synchronized Object get(){ Object t=null; while (list.size()==0){ try{ System.out.println("容器中已經空了,停止消費"); this.wait(); }catch (Exception e){ e.printStackTrace(); } } System.out.println("容器開始消費"); t=list.removeFirst(); count--; System.out.println("容器現在剩餘"+count); this.notifyAll(); return t; } public static void main(String[] args) { TestReetrantLock t=new TestReetrantLock(); //消費者 for (int i = 0; i <10 ; i++) { new Thread(()->{ for (int j = 0; j <5 ; j++) { t.get(); } }).start(); } try{ TimeUnit.SECONDS.sleep(1); }catch (Exception e){ e.printStackTrace(); } //生產者 for (int i = 0; i <2 ; i++) { new Thread(new Runnable() { @Override public void run() { for (int j = 0; j <25 ; j++) { t.put(Thread.currentThread().getName()); } } }).start(); } } }