【Java併發編程實戰】– 使用讀寫鎖實現同步數據訪問 lock_2

1、概述

ReentrantReadWriteLock(讀寫鎖),父接口:ReadWriteLock。java

這個類 有2個鎖,一個是 讀操做鎖,另外一個是 寫操做鎖。使用讀操做鎖時能夠容許多個線程同時訪問,可是使用寫操做鎖時只容許一個線程進行。在一個線程執行寫操做時,其餘線程不可以執行讀操做。dom

讀寫鎖:分爲讀鎖和寫鎖,多個讀鎖不互斥,讀鎖與寫鎖互斥,這是由jvm本身控制的,你只要上好相應的鎖便可。若是你的代碼只讀數據,能夠不少人同時讀,但不能同時寫,那就上讀鎖;若是你的代碼修改數據,只能有一我的在寫,且不能同時讀取,那就上寫鎖。總之,讀的時候上讀鎖,寫的時候上寫鎖!jvm

2、實現

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Queue3{
	
    private int data = 0;//共享數據,只能有一個線程能寫該數據,但能夠有多個線程同時讀該數據。
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    
    public void get(){
        rwl.readLock().lock();//上讀鎖,其餘線程只能讀不能寫
        System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " be ready to read data!");
        try {
            Thread.sleep((long)(Math.random()*1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " have read data :" + data);       
        rwl.readLock().unlock(); //釋放讀鎖,最好放在finnaly裏面
    }
     
    public void put(int data){
 
        rwl.writeLock().lock();//上寫鎖,不容許其餘線程讀也不容許寫
        System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " be ready to write data!");                   
        try {
            Thread.sleep((long)(Math.random()*1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.data = data;       
        System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " have write data: " + data);                   
         
        rwl.writeLock().unlock();//釋放寫鎖   
    }
}
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

public class MyRunnable implements Runnable{

	private int flat;
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	private Queue3 queue3;
	Random random = new Random();
	
	public MyRunnable(Queue3 queue3, int flat) {
		this.queue3 = queue3;
		this.flat = flat;
	}
	
	public void run() {
		if(flat == 0){  // 讀操做
		    queue3.get();
		}else if(flat == 1){  // 寫操做
			int data = random.nextInt(10);
			System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + " 隨機數爲:" + data);
			queue3.put(data);
		}else{
			System.out.println(sdf.format(new Date()) + " " + Thread.currentThread().getName() + "操做有誤!");
		}
	}

}
public class ReadWriteLockTest {
    public static void main(String[] args) {
        Queue3 queue3 = new Queue3();
        MyRunnable myReader = new MyRunnable(queue3, 0); // 讀操做
        MyRunnable myWriter = new MyRunnable(queue3, 1); // 寫操做
       
        for(int i=0;i<3;i++){
           Thread thread = new Thread(myReader);
           thread.start();
        }
       
        Thread thread = new Thread(myWriter);
        thread.start();
    }
}
//console結果:
2017-09-08 03:56:35 Thread-1 be ready to read data!
2017-09-08 03:56:35 Thread-2 be ready to read data!
2017-09-08 03:56:35 Thread-0 be ready to read data!
2017-09-08 03:56:35 Thread-3 隨機數爲:6
2017-09-08 03:56:35 Thread-1 have read data :0
2017-09-08 03:56:35 Thread-2 have read data :0
2017-09-08 03:56:35 Thread-0 have read data :0
2017-09-08 03:56:35 Thread-3 be ready to write data!
2017-09-08 03:56:36 Thread-3 have write data: 6
相關文章
相關標籤/搜索