1. Lock (锁的)接口

news/2024/5/20 9:27:27 标签: java, juc, 进程,

目录

1.1 复习synchronized

 1.2 Lock接口

1.3 Lock方法 

1.4 两者差异


1.1 复习synchronized

  他是Java的关键字,是一种同步,能够修饰 一个 对象,变量,方法,

   来控制这个所修饰的,被顺序的访问,

 多线程的编程步骤:

   第一:创建一个资源类,属性和操作方法

   第二:创建多线程,调用类里面的操作方法

结合synchronized 和 多线程的编程步骤实现卖票的功能(高内聚低耦合)

java">package Lock;
//多线程实现卖票的功能  synchronized方式
 class Ticket{ //第一步 资源类 票
     private int num =30; //定义票的数量
     public synchronized void sale(){  //synchronized
         //给这个资源加上,防止多线程的错误
           //资源的操作 卖票的方法
         if(num>0){
             System.out.println(Thread.currentThread().getName()+
                     " 卖出了: 1张 还剩下"+(num--)); }
     }
 }

public class SaleTicket {
     //第二步,创建多个线程,调用资源类的操作方法
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread t1 = new Thread(new Runnable() {
            @Override  //具体创建线程的方法是new Thread(new Runnable({ 重写run方法},线程名)
            public void run() {
                for(int i =0; i<10;i++){
                    ticket.sale();
                }
            }
        } ,"t1"
        );
        t1.start();
        Thread t2= new Thread(
          Thread t2= new Thread(  //Lambda 表达式
                () ->{ for (int i = 0; i < 10; i++) {
                        ticket.sale();
                    } } ,"t2"
        );
        t2.start();
       
    }
}

 代码执行的时候,t1 和 t2两个线程执行堆叠在一起,这是因为不同线程不同对象启动执行,都可以访问

 1.2 Lock接口

和等待条件提供一个框架的接口和类,不同于内置同步和监视器, LOCK是类,可通过类实现同步访问,多个接口实现类:可重入

lock的编程步骤同synchronized

可重入的代码定义private final ReentrantLock lock = new ReentrantLock(true);
lock.lock();

lock.unlock();
与解中的代码如果出现异常,解会执行不了,所以最好加try..finally

java">//第一步  创建资源类,定义属性和和操作方法
class LTicket {
    private int num = 30; //票数量
    private final ReentrantLock lock = new ReentrantLock(true);  //创建可重入
    public void sale() {   //卖票方法
        //上
        lock.lock();
        try {
            if(number > 0) { //判断是否有票
                System.out.println(Thread.currentThread().getName()+" :卖出 1张 剩余:"+(num--));
            }
        } finally {
            //解
            lock.unlock();
        }
    }
}

public class LSaleTicket {
    //第二步 创建多个线程,调用资源类的操作方法
    //创建三个线程
    public static void main(String[] args) {
        LTicket ticket = new LTicket();

new Thread(()-> {
    for (int i = 0; i < 40; i++) {
        ticket.sale();
    }
},"AA").start();

        new Thread(()-> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"BB").start();

        new Thread(()-> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"CC").start();
    }
}

1.3 Lock方法 

lock常用接口

java">public interface Lock {
	void lock();
	void lockInterruptibly() throws InterruptedException;
	boolean tryLock();
	boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
	void unlock();
	Condition newCondition();
}

lock()方法用来获取

  • 如果已被其他线程获取,则进行等待
  • 发生异常不会自动解,需用在 try{}catch{}块中进行
java">lock.lock();
try{
	//处理任务
}catch(Exception ex){
}finally{
	lock.unlock(); //释放
}

Condition 类也可以实现等待/通知模式

    关键字 synchronized 与 wait()/notify()这两个方法一起使用可以实现等待/通知模式,Lock 的 newContition()方法返回 Condition 对象,Condition 类也可以实现等待/通知模式

notify()通知时,JVM 会随机唤醒某个等待的线程, 使用 Condition 类可以进行选择性通知, Condition 比较常用的两个方法:

   1.  await()会使当前线程等待,同时会释放,当其他线程调用 signal()时,线程会重新获得并继续执行
   2. signal()用于唤醒一个等待的线程

ReentrantLock 是唯一实现了 Lock 接口的类,并且 ReentrantLock 提供了更多的方法
ReentrantLock可重入

Reentrant  ReadWriteLock 里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()和 writeLock()用来获取读和写
writeLock();来获取读
readLock();获取写

java">public interface ReadWriteLock {
 Lock readLock();
 Lock writeLock();
}

1.4 两者差异

synchronized与lock的异同:

   1. synchronized是java关键字,内置,而lock不是内置,是一个类,可以实现同步访问

                且 比 synchronized中的方法更加丰富
    2.synchronized不会手动释放,而lock需手动释放(不解会出现死,需要在 finally 块中释放
   3. lock等待的线程会相应中断,而synchronized不会相应,只会一直等待
   4.  通过 Lock 可以知道有没有成功获取,而 synchronized 却无法办到
   5.   Lock 可以提高多个线程进行读操作的效率(当多个线程竞争的时候)


http://www.niftyadmin.cn/n/1712932.html

相关文章

2.什么是线程间的通信 ?怎么实现线程通信

2.1什么是线程通信以及实现步骤 线程间通信的模型有两种&#xff1a;共享内存和消息传递 线程通信其实就是 &#xff0c;实现线程的交替工作&#xff0c;并传递信息 线程间的通信具体步骤&#xff1a;&#xff08;涉及上中下部&#xff09; 创建资源类&#xff0c;在资源类中…

3 . 线程间定制化通信 (交替完成规定的工作)

案列&#xff1a;启动三个线程&#xff0c;按照如下要求&#xff1a; AA打印5此&#xff0c;BB打印10次&#xff0c;CC打印15次&#xff0c;一共进行10轮 具体思路&#xff1a; 每个线程添加一个标志位&#xff0c;是该标志位则执行操作&#xff0c;并且修改为下一个标志位&am…

4. 集合 的线程安全 (可以看到底层的集合是没有加锁的)

4.1集合不安全的问题 在讲解线程安全的之前&#xff0c;先看线程不安全的 实例 创建 ArrayList集合 并使用线程 再集合中添加元素获取元素 //创建ArrayList集合 List<String> list new ArrayList<>(); for (int i 0; i <30; i) {new Thread(()->{//向集合…

5. 多线程锁 (公平锁和非公平锁,死锁,可重锁)

某一个时刻内&#xff0c;只能有唯一 一个线程去访问这些synchronized 方法 所有的静态同步方法用的也是同一把锁——类对象本身&#xff0c;这两把锁是两个不同的对象&#xff0c;所以静态同步方法与非静态同步方法之间是不会有竞态条件的但是一旦一个静态同步方法获取锁后&am…

JUC高并发编程的学习,知识点详细概括

JUC 的概述 https://blog.csdn.net/qq_52252193/article/details/121903199 一.Lock 接口的概述 1. Lock &#xff08;锁的&#xff09;接口_想成为大神说32的博客-CSDN博客 二.线程间的通信 (Sysnchronized. Lock,的案例&#xff09; 2.什么是线程间的通信 &#xff1f;怎么实…

二叉树的三种遍历算法的实现(前序、中序、后序)递归与非递归

二叉树的三种遍历算法的实现&#xff08;前序、中序、后序&#xff09;递归与非递归 1、二叉树的定义 二叉树是n&#xff08;n>0&#xff09;个数据元素的有限集&#xff0c;含有唯一的称为根的元素&#xff0c;且&#xff0c;其余元素分成两个互不相交的子集&#xff0c;…

6. Callable接口

创建线程的多种方式&#xff1a; 继承Thread类实现Runnable接口Callable接口线程池 目前学习了有两种创建线程的方法&#xff0c;一种是通过创建 Thread 类&#xff0c;另一种是通过使用 Runnable 创建线程&#xff0c;但是&#xff0c;Runnable 缺少的一项功能是&#xff0c;…

数组和指针的几点理解

数组和指针的理解 1.1数组 1.1.1、数组定义 一组具有同名的同属性的数据就组成了一个数组&#xff08;array&#xff09; 由此可以知道&#xff1a; 1、数组是一组有序数据集合。数组中个数据的排列具有一定的规律&#xff0c;下标代表数据在数组中的序号。 int a[10];方括…