標籤:存在 寫入 object pre rgs col ide ons AC
說明:先上代碼,筆記後續補充
public class CoderTest1 {
private static Object key;
public static void main(String[] args) {
//同步容器 Vector HashTable Collections.synchronizedList()
//如果迭代過程中發生修改,並發修改異常 修改線程獨立copy一份集合(這樣會導致不能得到最新的資料,效率有影響)
/*多個線程操作容易拋出ArrayIndexOutOfBoundsException異常
* Vector<Object> vector = new Vector<>();
int lastSize = vector.size()-1;
vector.remove(lastSize);
* */
// Vector<Object> vector = new Vector<>();
// synchronized (key){
// int lastSize = vector.size()-1;
// vector.remove(lastSize);
// }
//這種情況會出現並發修改異常 ConcurrentModificationException
// ArrayList<Object> list = new ArrayList<>();
// list.add(1);
// list.add(1);
// list.add(1);
// list.add(1);
// list.add(1);
// for (Object obj : list){
// System.out.println(obj);
// list.remove(obj);
// }
//並發容器 ConcurrentHashMap 分段鎖 每一個鏈表上一個鎖,1.8之後好像是node鎖
//map.putIfAbsent 只有key不存在才會操作成功,不會覆蓋
//CopyOnWriteArrayList/Set 應用情境:讀操作多,寫操作很少
//阻塞隊列
// 先進先出,如果隊列為空白則阻塞
// ConcurrentHashMap map = new ConcurrentHashMap();
// map.putIfAbsent(1,2);
// map.putIfAbsent(1,3);
// System.out.println(map);
//
// CopyOnWriteArrayList<Object> list = new CopyOnWriteArrayList<>();
// BlockingQueue queue = new ArrayBlockingQueue(2);
// 1閉鎖 2柵欄 3訊號量
//到達柵欄之後需要所有線程執行完之後才能繼續執行其他線程
// final CountDownLatch latch = new CountDownLatch(2);
// //第一個線程
// new Thread(){
// public void run(){
// try {
// System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");
// Thread.sleep(3000);
// System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");
// latch.countDown();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }.start();
// //第二個線程
// new Thread(){
// public void run(){
// try {
// System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");
// Thread.sleep(3000);
// System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");
// latch.countDown();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }.start();
//
// try {
// System.out.println("等待兩個子線程執行完畢。。。");
// //閉鎖
// latch.await();
// System.out.println("兩個子線程已經執行完畢。。。");
// System.out.println("繼續執行主線程");
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N);
for (int i=0; i<N; i++){
new Writer(barrier).start();
}
int workNum = 8;//工人數目
Semaphore semaphore = new Semaphore(5);//訊號量,機器數目
for (int i=0; i<workNum; i++){
new Worker(i,semaphore).start();
}
}
//用於柵欄
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run(){
System.out.println("線程"+Thread.currentThread().getName()+"正在寫入資料。。。");
try {
Thread.sleep(5000);
System.out.println("線程"+Thread.currentThread().getName()+"寫入資料完畢,等待其他線程寫入資料。。。");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有線程寫入資料完畢,繼續執行其他任務。。。");
}
}
//用於訊號量
static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num, Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run(){
try {
semaphore.acquire();
System.out.println("工人"+this.num+"佔用一個機器生產。。。");
Thread.sleep(3000);
System.out.println("工人"+this.num+"釋放出機器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
JAVA並發編程2