Java線程學(xué)習(xí)-Lock

Lock

Lock是Java提供給開發(fā)者JDK級別的一種控制代碼同步訪問的工具類。只有一個(gè)子類ReentrantLock。功能和synchronized差不多。使用也是非常的簡單

class Test {
    private Lock lock = new ReentrantLock();
  
    //需要同步訪問的方法
    private void doSomething() {
        lock.lock();
        
        try {
            //do something
        } catch (Exception e) {

        }finally {
            lock.unlock();
        }
    }
}

例子

    private void lockTest() {
        sendMessage("lockTest begin");
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    doSomething();
                }
                sendMessage("thread-1 end");
            }
        }, "thread-1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    doSomething();
                }
                sendMessage("thread-2 end");
            }
        }, "thread-2").start();
    }

   //一次訪問這個(gè)函數(shù)
    private void doSomething() {
        lock.lock();

        try {
            Thread.sleep(100);
            sendMessage(Thread.currentThread().getName() + " doSomething");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

輸出:


image.png

ReadWriteLock

同步讀寫操作的一個(gè)鎖。和Lock完全沒有任何關(guān)系。

  • 允許多個(gè)線程同時(shí)進(jìn)行讀操作。
  • 不允許多個(gè)線程同時(shí)寫操作,只會(huì)誰拿到鎖誰先去執(zhí)行寫操作。
  • 多個(gè)線程既有讀又有寫操作,沒有線程進(jìn)入寫或者等待寫,就可以多個(gè)線程讀了;進(jìn)入寫操作后,不允許其他線程讀或者寫
讀操作
    private void readLockTest() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                readSomething();
            }
        }, "t1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                readSomething();
            }
        }, "t2").start();
    }

    private void readSomething() {
        readWriteLock.readLock().lock();
        try {
            Iterator<String> iterator = cacheList.iterator();
            while (iterator.hasNext()) {
                Thread.sleep(100);
                sendMessage(Thread.currentThread().getName() + "讀取 -- "+ iterator.next());
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            readWriteLock.readLock().unlock();
        }
    }

輸出:


image.png
寫操作
   private void writeLockTest() {
        final Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                writeSomething();
            }
        }, "t1");
        t1.start();

        final Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                writeSomething();
            }
        }, "t2");
        t2.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendMessage("寫完了");
                for (String s : cacheList) {
                    sendMessage(s);
                }
            }
        }).start();
    }

    private void writeSomething() {
        readWriteLock.writeLock().lock();
        try{
            for (int i = 0; i < 10; i++) {
                Thread.sleep(100);
                cacheList.add("這是第" + i + "元素");
                sendMessage(Thread.currentThread().getName() + "寫入---這是第" + i + "元素");
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            readWriteLock.writeLock().unlock();
        }
    }

輸出:


image.png
讀寫同時(shí)進(jìn)行
    private void readWriteLockTest(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                writeSomething();
            }
        }, "t1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                readSomething();
            }
        }, "t2").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                readSomething();
            }
        }, "t3").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                writeSomething();
            }
        }, "t4").start();

輸出:


image.png

測試方法中有四個(gè)線程,分別是:,,;日志中在t2讀的時(shí)候,這是t3啟動(dòng)了,t3是讀的操作,此時(shí)并沒有寫或者等待寫的操作,所以t3也開始讀,最終t2和t3同時(shí)讀。

把測試方法順序改一下,分別是:,,;
輸出:

image.png

可以看出在t2的時(shí)候,t3啟動(dòng)了,因?yàn)閠3是寫操作,所以t4啟動(dòng)后,因?yàn)閠3已經(jīng)等待寫,所以t4會(huì)在t3寫完后才執(zhí)行。

demo源碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文章來源:http://www.54tianzhisheng.cn/2017/06/04/Java-Thread/...
    beneke閱讀 1,906評論 0 1
  • 進(jìn)程:正在執(zhí)行的程序,是一個(gè)動(dòng)態(tài)的過程 線程:是進(jìn)程中用于控制程序執(zhí)行的控制單元(執(zhí)行路徑,執(zhí)行情景) 進(jìn)程中至少...
    寶塔山上的貓閱讀 512評論 0 1
  • 下面是我自己收集整理的Java線程相關(guān)的面試題,可以用它來好好準(zhǔn)備面試。 參考文檔:-《Java核心技術(shù) 卷一》-...
    阿呆變Geek閱讀 15,137評論 14 507
  • *每一個(gè)生命都值得被珍惜。 2017年6月24日。 我的大學(xué)生活完完整整地結(jié)束了。 留下很多遺憾,留下很多無法彌補(bǔ)...
    新兒爺閱讀 278評論 0 0
  • 目錄 1、美好的愿望 2010年夏天,藍(lán)心微16歲生日時(shí)許了個(gè)美好的愿望,記在了她心愛的粉色筆記本上:“我希望和萱...
    陸Nene閱讀 454評論 2 2

友情鏈接更多精彩內(nèi)容