程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> 線程-懂java中lock鎖的請進

線程-懂java中lock鎖的請進

編輯:編程解疑
懂java中lock鎖的請進
 package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Foo {

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private final Lock r = rwl.readLock();

    private final Lock w = rwl.writeLock();

    public void read() {
        try {
            r.lock();
            Thread.sleep(1000);
            System.out.println("read...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            r.unlock();
        }

    }

    public void wirte() {

        try {
            w.lock();
            Thread.sleep(1000);
            System.out.println("writing...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            w.lock();
        }
    }
}

上面是我在書上看到的代碼

書上說讓我寫一個實現runnable接口的類
然後測試讀寫鎖

我沒明白,誰能解釋下

最佳回答:


首先,你這個Foo對象必須是被多個線程共享的,然後定義兩個任務,一個執行讀操作,另一個任務執行寫操作,然後定義2個寫線程,5個讀線程,測試這些線程分別執行讀、寫操作時不同鎖的特點。
其次,你的這個Foo類定義的write的finally分支錯誤了,應該是w.unlock()才對,稍微修正下你的Foo代碼,輸出當前線程的名稱:

 import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Foo {

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private final Lock r = rwl.readLock();

    private final Lock w = rwl.writeLock();

    // 讀鎖,允許同時N個線程進行讀操作,不存在競爭
    public void read() {
        try {
            r.lock();
            Thread.sleep(10000);
            System.out.println(Thread.currentThread().getName() + " read...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            r.unlock();
        }

    }

    //寫鎖,同時允許一個線程寫,明顯能看到互斥等待
    public void wirte() {

        try {
            w.lock();
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + " writing...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            w.unlock();
        }
    }
}

定義讀任務:

 public class LockReadTask implements Runnable{

    private Foo source;

    public LockReadTask(Foo source){
        this.source = source;
    }

    @Override
    public void run() {
        source.read();
    }

}

定義寫任務:

 public class LockWriteTask implements Runnable{
    private Foo source;

    public LockWriteTask(Foo source){
        this.source = source;
    }

    @Override
    public void run() {
        source.wirte();
    }
}

測試代碼,定義2個寫線程,看寫鎖的競爭狀態;4個讀線程,讀鎖步存在競爭。

 public class Main {
    public static void main(String[] args) {
        //定義共享數據源
        Foo source = new Foo();

        //開啟2個寫線程:能明顯看到t1,t2寫線程之間的互斥等待
        Thread t1 = new Thread(new LockWriteTask(source));
        t1.setName("write-Thread-1");
        Thread t2 = new Thread(new LockWriteTask(source));
        t2.setName("write-Thread-2");
        t1.start();
        t2.start();

        //開啟5個讀線程:讀鎖,允許同時N個線程進行操作,可以看到讀打印操作同時秒出
        Thread rt1 = new Thread(new LockReadTask(source));
        rt1.setName("read-Thread-1");
        Thread rt2 = new Thread(new LockReadTask(source));
        rt2.setName("read-Thread-2");
        Thread rt3 = new Thread(new LockReadTask(source));
        rt3.setName("read-Thread-3");
        Thread rt4 = new Thread(new LockReadTask(source));
        rt4.setName("read-Thread-4");

        rt1.start();
        rt2.start();
        rt3.start();
        rt4.start();
    }
}   

可以看到測試結果:寫線程之間有競爭,輸出信息由先後;而都線程之間的讀鎖匙共享的,沒有競爭,所以輸出是同時秒出的。

u013179958
wojiushiwo945you
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved