Java馬士兵高併發編程視頻學習筆記(二)

1.ReentrantLock的簡單使用  

Reentrant n.再進入java

ReentrantLock 一個可重入互斥Lock具備與使用synchronized方法和語句訪問的隱式監視鎖相同的基本行爲和語義,但具備擴展功能。(從jdk1.8中文版複製而來)函數

能夠完成synchronized相同的做用,但必須手動釋放鎖this

package com.dingyu2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Reentrant n.再進入 * ReentrantLock 一個可重入互斥Lock具備與使用synchronized方法和語句訪問的隱式監視鎖相同的基本行爲和語義,但具備擴展功能。(從jdk1.8中文版複製而來) * 能夠完成synchronized相同的做用,但必須手動釋放鎖 * @author dingyu * */
public class ReentrantLock1 { private Lock lock = new ReentrantLock(); public void m1() { try { lock.lock();//synchronized(this)相似,鎖定的是堆的對象 for (int i = 0; i < 10; i++) System.out.println("m1-" + i); } catch (Exception e) { System.out.println("m1啓動"); } finally { System.out.println("m1結束"); lock.unlock(); } } public void m2() { try { lock.lock(); for (int i = 0; i < 10; i++) System.out.println("m2-" + i); } catch (Exception e) { System.out.println("m2啓動"); } finally { System.out.println("m2結束"); lock.unlock(); } } public static void main(String[] args) { ReentrantLock1 reentrantLock1 = new ReentrantLock1(); new Thread(() -> reentrantLock1.m1()).start(); new Thread(() -> reentrantLock1.m2()).start(); } }

2.ReentrantLock對synchronized的擴展之tryLock()

package com.dingyu2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * ReentrantLock對synchronized的擴展之tryLock() * * @author dingyu * */
public class ReentrantLock2 { private Lock lock = new ReentrantLock(); public void m1() { lock.lock();// 一直鎖着,不手動釋放, 和synchronized(this)相似,鎖定的是堆的對象
 } public void m2() { boolean isNotLock = lock.tryLock();// 若是別的進程鎖着就返回false,若是沒鎖返回true // 咱們能夠根據有沒有鎖來執行本身的邏輯,而不須要等着鎖的釋放,更加靈活
        if (isNotLock) { System.out.println("lock對象沒有被鎖定"); } else { System.out.println("lock對象被鎖定了"); } } public static void main(String[] args) { ReentrantLock2 reentrantLock2 = new ReentrantLock2(); new Thread(() -> reentrantLock2.m1()).start(); new Thread(() -> reentrantLock2.m2()).start(); } }

3.ReentranLock對synchronized的擴展:能夠被另外的線程打斷

package com.dingyu2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * ReentranLock對synchronized的擴展:能夠被另外的線程打斷 * 由於m1方法一直佔着鎖,m2永遠不可能獲得鎖,既然得不到鎖,咱們就關閉m2好了,這時候得用lockInterruptibly * * @author dingyu * */
public class ReentrantLock3 { private Lock lock = new ReentrantLock(); public void m1() { lock.lock(); try { System.out.println("t1 start"); while (true) { } } finally { lock.unlock(); System.out.println("t1 end"); } } public void m2() { try { lock.lockInterruptibly(); System.out.println("t2 start"); } catch (InterruptedException e) { System.out.println("t2被打斷了"); } finally { if (lock.tryLock()) lock.unlock(); System.out.println("t2 end"); } } public static void main(String[] args) { ReentrantLock3 reentrantLock3 = new ReentrantLock3(); Thread t1 = new Thread(() -> reentrantLock3.m1(), "t1"); t1.start(); Thread t2 = new Thread(() -> reentrantLock3.m2(), "t2"); t2.start(); t2.interrupt(); } }

4.ReentrantLock對synchronized的擴展 : 能夠指定公平鎖

import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * ReentrantLock對synchronized的擴展 : 能夠指定公平鎖,哪一個線程等待時間長,哪一個先執行 * 在構造函數中放入ture參數 * * @author dingyu * */
public class ReentrantLock4 { private Lock lock = new ReentrantLock(true); public void m1() { for (int i = 0; i < 10; i++) { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "running"); } finally { lock.unlock(); } } } public static void main(String[] args) { ReentrantLock4 lock4 = new ReentrantLock4(); new Thread(()->lock4.m1(),"t1").start(); new Thread(()->lock4.m1(),"t2").start(); } }

5.使用wait和notifyAll實現消費者生產者模式

package com.dingyu2; import java.util.LinkedList; /** * 使用wait和notifyAll實現消費者生產者模式 * * @author dingyu * */
public class ProduceConsumer { private final LinkedList<Integer> lists = new LinkedList<Integer>(); private final int MAX = 10; private int count = 0; public synchronized void put(Integer i) { while (lists.size() == MAX) { // wait大多數狀況和while一塊兒用
            try { this.wait();// 若是滿了我就釋放鎖,而且等待
            } catch (InterruptedException e) { e.printStackTrace(); } } lists.add(i);// 生產一個
        count++; this.notifyAll();// 叫醒消費者能夠消費啦
 } public synchronized Integer get() { while (lists.size() == 0) { try { this.wait();// 若是集合爲空,不能消費,釋放鎖,等着
            } catch (InterruptedException e) { e.printStackTrace(); } } Integer num = lists.removeFirst(); count--; this.notifyAll();// 叫醒生產者,能夠繼續生產啦
        return num; } }

6.使用Condition 完成生產者消費者模式

package com.dingyu2; /** * 使用Condition 完成生產者消費者模式 * @author dingyu * */

import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProduceConsumer2 { private final LinkedList<Integer> lists = new LinkedList<Integer>(); private final int MAX = 10; private int count = 0; private Lock lock = new ReentrantLock(); private Condition p = lock.newCondition();// 生產者
    private Condition c = lock.newCondition();// 消費者

    public void put(Integer i) { try { lock.lock(); while (lists.size() == MAX) { try { p.await(); } catch (InterruptedException e) { e.printStackTrace(); } } lists.add(i); count++; c.signalAll(); } finally { lock.unlock(); } } public Integer get() { Integer i = null; try { lock.lock(); while (lists.size() == 0) { try { c.await(); } catch (InterruptedException e) { e.printStackTrace(); } } i = lists.removeFirst(); count++; p.signalAll(); } finally { lock.unlock(); } return i; } }

 7.ThreadLocal 線程局部變量  每一個線程中的這個變量歸本身線程管

package com.dingyu; public class ThreadLocal1 { private ThreadLocal<Integer> tl = new ThreadLocal<Integer>(); public void m1() { System.out.println(tl.get()); } public void m2() { tl.set(7898); } public static void main(String[] args) { ThreadLocal1 local1 = new ThreadLocal1(); new Thread(() -> local1.m2()).start(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> local1.m1()).start(); } }
相關文章
相關標籤/搜索