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

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的测试类:

复制代码
 1 import java.util.Arrays;
 2  
 3 public class TestMylist {
 4     public static void main(String[] args) throws Exception{
 5     Mylist mylist = new Mylist();
 6     Runnable runnable=new Runnable() {
 7         @Override
 8         public void run() {
 9             mylist.add("hello");
10         }
11     };
12         Runnable runnable2=new Runnable() {
13             @Override
14             public void run() {
15                 mylist.add("world");
16             }
17         };
18  
19         Thread t1=new Thread(runnable);
20         Thread t2=new Thread(runnable2);
21  
22         t1.start();
23         t2.start();
24  
25         t1.join();
26         t2.join();
27  
28         System.out.println(Arrays.toString(mylist.getStr()));
29  
30  
31     }
32 }
复制代码

 

 

在锁之中调用一个锁,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));
    }
}
复制代码

 

posted @   逃逸线LinesOfFlight  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示