java多线程编程(5)ReentrantReadWriteLock和ReentrantLock

前言

java中多线程编码中除了synchronized 关键词以外,就是使用lock接口实现锁。本次就讲一相关实现

ReentrantLock

ReentrantLock的第一个例子可以简单的用于一个锁。锁定一个变量,只有当线程获得锁的时候才可以对变量进行修改。下面的代码举例的了我锁住了一个静态变量。即使多线程修改,也不会出现多线程问题。相反如果去掉锁,会发现变量的修改会出现多线程问题

import java.util.concurrent.locks.ReentrantLock;

public class Test20 extends Thread{

    public static int result = 0;
    public static class Test extends Thread{
        private ReentrantLock lock;
        public Test(ReentrantLock lock) {
            this.lock = lock;
        }

        public void run(){
            while (true){
            	//可以去除lock和unlock发现发生了线程不安全
                lock.lock();
                result++;
                System.out.println("thread"+Thread.currentThread().getName()+",result"+result);
                lock.unlock();
            }
        }


    }
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock(true);
        Test test1 = new Test(lock);
        Test test2 = new Test(lock);
        Test test3 = new Test(lock);
        test1.setName("test1");
        test2.setName("test2");
        test3.setName("test3");
        test1.start();
        test2.start();
        test3.start();
    }
}

trylock()可以在一段时间内获得一个锁,可以看到获得锁的线程begin了,然后看到try失败的线程也迅速进入,进行了begin。表明trylock()成功了。

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class Test21 extends Thread{
    private ReentrantLock lock;
    public Test21(ReentrantLock lock) {
        this.lock = lock;
    }

    public void run(){
        while (true){
            boolean locked = false;
            try {

                locked = lock.tryLock(1000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread"+Thread.currentThread().getName()+"begin");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread"+Thread.currentThread().getName()+"next");
            if(locked){
                lock.unlock();
            }

        }
    }

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock(true);
        Test21 test1 = new Test21(lock);
        Test21 test2 = new Test21(lock);
        Test21 test3 = new Test21(lock);
        test1.setName("test1");
        test2.setName("test2");
        test3.setName("test3");
        test1.start();
        test2.start();
        test3.start();
    }
}

ReentrantReadWriteLock

可以看到写了2个类,一个进行写,一个进行读,可以看到每次读线程都会同时进行,写线程是单独进行的。交替进行,在写线程进行写的时候会卡住读线程的相关操作,但是读线程是可以并发进行的。各个读之间不受影响

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test22 extends Thread{
    public static int result = 0;
    static class Test22A extends Thread{
        private ReentrantReadWriteLock lock;
        public Test22A(ReentrantReadWriteLock lock) {
            this.lock = lock;
        }

        public void run(){
            while (true){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.writeLock().lock();
                System.out.println("result change");
                result = result+1;
                System.out.println("thread:"+Thread.currentThread().getName()+",result:"+result);
                lock.writeLock().unlock();
            }

        }
    }
    static class Test22B extends Thread {
        private ReentrantReadWriteLock lock;

        public Test22B(ReentrantReadWriteLock lock) {
            this.lock = lock;
        }

        public void run() {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.readLock().lock();
                System.out.println("thread:" + Thread.currentThread().getName() + ",result:" + result);
                lock.readLock().unlock();
            }
        }
    }

    public static void main(String[] args) {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
        Test22B b1 = new Test22B(lock);
        Test22B b2 = new Test22B(lock);
        Test22B b3 = new Test22B(lock);
        Test22B b4 = new Test22B(lock);

        Test22A a1 = new Test22A(lock);
        Test22A a2 = new Test22A(lock);
        b1.setName("b1");
        b2.setName("b2");
        b3.setName("b3");
        b4.setName("b4");
        a1.setName("a1");
        a2.setName("a2");
        a1.start();
        a2.start();
        b1.start();
        b2.start();
        b3.start();
        b4.start();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章