Java线程(Lock接口,重入锁,读写锁)

本文介绍了Java并发编程中ReentrantLock(可重入锁)与读写锁的使用,对比了ReentrantLock与synchronized的优劣,并通过实例展示了如何在多线程环境下实现线程安全。文中详细讲解了ReentrantLock的lock、tryLock、unlock方法,以及读写锁的互斥规则,并提供了实际的售票和数据读写案例来加深理解。
摘要由CSDN通过智能技术生成

Lock接口、重入锁

 JDK1.5加入,与synchronized相比较,显示、定义、结构更加灵活。即性能更加优越。

常用方法:

void lock()                   获取锁,如果锁被占用,则等待。

Boolean Trylock()             尝试获取锁,成功则返回true,锁被占用则等待,不阻塞

Void unlock()                释放锁

在锁之中调用一个锁,ReentrantLock,类似于互斥锁synchronized。

需求说明,将hello\world两个词加入拥有五个位置的数组当中。

代码示例:

MyList类:

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;



public class Mylist {

    private Lock lock=new ReentrantLock();

    private String[] str={"A","B","","",""};

    private int count=2;



    public void add(String value){

        lock.lock();



        str[count]=value;



//防止进程太快

        try {

            Thread.sleep(1000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } finally {

            lock.unlock();

        }

    }



    public  String[] getStr(){

        return str;

    }

}

MyList的测试类:

import java.util.Arrays;

public class TestMylist {
    public static void main(String[] args) throws Exception{
    Mylist mylist = new Mylist();
    Runnable runnable=new Runnable() {
        @Override
        public void run() {
            mylist.add("hello");
        }
    };
        Runnable runnable2=new Runnable() {
            @Override
            public void run() {
                mylist.add("world");
            }
        };

        Thread t1=new Thread(runnable);
        Thread t2=new Thread(runnable2);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println(Arrays.toString(mylist.getStr()));


    }
}

在锁之中调用一个锁,ReentrantLock,类似于互斥锁synchronized。

卖票案例的ReentrantLock写法:

Ticket类:

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

public class Ticket implements Runnable{
    private int ticket =100;
    private Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true){
            lock.lock();
            try {
                if (ticket<0){
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"卖了第:"+ticket+"张票");
                ticket--;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

对于Ticket的测试类:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestTicket {
    public static void main(String[] args) {
        Ticket ticket=new Ticket();
        ExecutorService es=Executors.newFixedThreadPool(4);
        for (int i=0;i<=4;i++){
            es.submit(ticket);
        }
        es.shutdown();
    }
}

读写锁

读锁不互斥,写锁互斥。运行效率高

互斥规则:

写-写:互斥,阻塞

读-写:互斥,读阻塞写,写阻塞读

读-读:不互斥,不阻塞

在读操作远远高于写操作的环境中,可在保障线程安全的情况下,提高运行效率。

代码示例:

ReentrantReadWriteLock:

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

public class ReadWriteDemo {
//    创建读写锁
    private ReentrantReadWriteLock rr1 = new ReentrantReadWriteLock();
//    获取读锁
    private ReentrantReadWriteLock.ReadLock readLock=rr1.readLock();
//    创建写锁
    private ReentrantReadWriteLock.WriteLock writeLock=rr1.writeLock();

    private  String value;

    public String getValue(){
        readLock.lock();
        try {
            try {
//            拿到数据前休眠一会,让程序变慢
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("读取:"+this.value);
            return this.value;
        } finally {
            readLock.unlock();
        }

    }

    public void setValue(String value){
        writeLock.lock();
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("写入:"+value);
            this.value=value;
        } finally {
            writeLock.unlock();
        }
    }
}

测试类:

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestReadWriteLock {
    public static void main(String[] args) {
        ReadWriteDemo readWriteDemo=new ReadWriteDemo();
//        创建线程池
        ExecutorService es = Executors.newFixedThreadPool(20);

        Runnable read = new Runnable() {
            @Override
            public void run() {
                readWriteDemo.getValue();
            }
        };

        Runnable write = new Runnable() {
            @Override
            public void run() {
//产生一个1000以内的随机数作为张三的年龄
                readWriteDemo.setValue("张三:"+new Random().nextInt(100));
            }
        };

        long start=System.currentTimeMillis();
//        分配18读取任务
        for (int i = 0;i < 18;i++){
            es.submit(read);
        }
        for (int j = 0; j < 2;j++ ){
            es.submit(write);
        }

        es.shutdown();//关闭线程

        while(!es.isTerminated()){//相当于机器的空转,等待上面的任务全部完成

        }

        long end = System.currentTimeMillis();
        System.out.println("用时="+(end-start));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃逸线LOF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值