关于Lock锁

news/2024/11/23 22:53:59/

Synchronized锁的缺陷
Synchronized不会手动释放锁资源,当线程发生阻塞后,其他线程只能眼睁睁的等着,不会分别是读线程和写线程,读问题并不会引发高并发,但是synchronized锁不能识别是读线程还是锁线程 ,遇到了都会锁上。另外没有中断锁的功能,一个线路等待时间过长不会自我中断线程。

Lock锁
一、概述
1.Lock是JDK1.5中提供的一套用于取代synchronized的机制
2.相对synchronized而言,Lock更加灵活和精细 - synchronized在使用的时候需要确定锁对象,如果确定错误或者锁形成嵌套,容易出现死锁;Lock由程序员自己创建,在使用的时候无需找锁对象而是直接调用方法加锁解锁即可

1.ReentrantLock - 重入锁:允许锁资源被同一个线程多次占用,也允许这个锁资源被不同的线程占用
2.锁的公平和非公平策略:
1.在资源有限的情况下,线程之间实际抢占执行到的次数不一定均等,这种现象称之为非公平策略
2.公平策略在使用的时候需要定义队列,而线程并不是直接抢占资源而是抢占入队顺序,这种情况下每一个线程的执行次数是大致相等

3.相对非公平策略而言,公平策略需要耗费更多的内存,需要涉及到线程调度,所以公平策略的效率相对较低
4.Lock和synchronized默认是非公平策略

 ·公平锁: ReentrantLock pairLock =new eentrantLock(true)--相当于,线程需要进入队列中等待,调用使用完后又进入队咧最后,重新等待。先进先出。 

·非公平锁: ReentrantLock pairLock =new ReentrantLock(false 构造函 数不传
数,则默认是非公平锁

二 其他
1.CountDownLatch:闭锁/线程递减锁。会对线程进行计数,在计数归零之前会进行阻塞,直到计数归零才会放开阻塞 - 一组线程结束之后开启另一组线程
public class CountDownLatchDemo {

public static void main(String[] args) throws InterruptedException {CountDownLatch cdl = new CountDownLatch(7);new Thread(new Teacher(cdl)).start();new Thread(new Teacher(cdl)).start();new Thread(new Student(cdl)).start();new Thread(new Student(cdl)).start();new Thread(new Student(cdl)).start();new Thread(new Student(cdl)).start();new Thread(new Student(cdl)).start();// 正常情况下:应该是考官和考生都到达考场之后才能开始考试// 在上面七个线程执行完成之前,主线程应该陷入阻塞// 在计数归零之前,需要阻塞cdl.await();System.out.println("开始考试");}

}

class Teacher implements Runnable {

private CountDownLatch cdl;public Teacher(CountDownLatch cdl) {this.cdl = cdl;
}@Override
public void run() {try {// 模拟考官到考场的时间Thread.sleep((long) (Math.random() * 10000));System.out.println("考官到达考场");// 减少一个计数cdl.countDown();} catch (InterruptedException e) {e.printStackTrace();}
}

}

class Student implements Runnable {

private CountDownLatch cdl;public Student(CountDownLatch cdl) {this.cdl = cdl;
}@Override
public void run() {try {// 模拟考生到达考场的时间Thread.sleep((long) (Math.random() * 10000));System.out.println("考生到达考场");cdl.countDown();} catch (InterruptedException e) {e.printStackTrace();}
}

}

1.CyclicBarrier:栅栏。会对线程进行计数,在计数归零之前会进行阻塞,直到计数归零才会放开阻塞 - 这一组线程到达同一个点之后在分别继续往下执行
/*
举例:跑步比赛
所有的运动员都到了起跑线之后,才能往外跑
*/
public class CyclicBarrierDemo {

public static void main(String[] args) {CyclicBarrier cb = new CyclicBarrier(6);new Thread(new Runner(cb), "1号").start();new Thread(new Runner(cb), "2号").start();new Thread(new Runner(cb), "3号").start();new Thread(new Runner(cb), "4号").start();new Thread(new Runner(cb), "5号").start();new Thread(new Runner(cb), "6号").start();}

}
fdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxfdxxxxxxxxxxxxxxxxxxffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx// 运动员
class Runner implements Runnable {

private CyclicBarrier cb;public Runner(CyclicBarrier cb) {this.cb = cb;
}@Override
public void run() {try {// 模拟每一个人到起跑线的时间Thread.sleep((long) (Math.random() * 10000));String name = Thread.currentThread().getName();System.out.println(name + "运动员到了起跑线");// 正常情况下:应该是所有的运动员都到了起跑线之后才能往外跑// 也就意味着先到的运动员应该在这儿等待,等大家到齐再往外跑// 在阻塞的时候同时减少计数,当计数归零之后放开阻塞cb.await();System.out.println(name + "运动员跑了出去");} catch (Exception e) {e.printStackTrace();}}

}

、、


http://www.ppmy.cn/news/903644.html

相关文章

KeyLock

在这篇文章https://bbs.csdn.net/topics/390523873基础上改进的 public class KeyLock<K> {// 保存所有锁定的KEY及其信号量private final ConcurrentMap<K, Semaphore> map new ConcurrentHashMap<K, Semaphore>();// 保存每个线程锁定的KEY及其锁定计数p…

[转贴]What's the Scroll Lock key on my computer for?

你知道键盘上Scroll Lock键有什么用吗&#xff1f;可能大多数人都不知道这个键&#xff0c;恐怕它只是为了点亮键盘上的一个灯而以。但从原来DOS以来的人们估计或多或少的知道这个键是用于滚动锁定的&#xff0c;那具体是怎么一回事呢&#xff1f;请看下文&#xff1a;[原文链接…

CBlock

第三章 本章将介绍一些新的数据结构。除非特别说明&#xff0c;本章提到的所有的类与函数均位于main.h或main.cpp。 每个节点均保存有一个区块链副本。区块链由相互连接的区块&#xff08;CBlock实例&#xff09;所构成。每个区块包含多笔交易&#xff08;CTransaction实力&…

wholocking me

今天在cmd下边查看一个ax的时候&#xff0c;发现它没有用&#xff0c;准备del掉它&#xff0c;没有想到却说 “拒绝访问。” 难道是因为有其他的进程转载了它&#xff0c;不能删除。 想起了用到的wholocking me工具&#xff0c;看看是哪个进程装载了它。不过这个工具是GUI的&am…

文件被system进程锁定,不能删除

文件被system进程锁定&#xff0c;不能删除&#xff0c;没有明显用户进程操作此文件。 软件UNLOCKER,WHOLOCKME,LOCK HUNTER之类的&#xff0c;可能需要重启才能解决问题&#xff0c;这在生产环境 中是不可接受的。 能作的还是慢慢搜索可用解决方案。。 然后&#xff0c;找到此…

ShedLock锁

ShedLock是一个锁&#xff0c;官方解释是他永远只是一个锁&#xff0c;并非是一个分布式任务调度器。一般shedLock被使用的场景是&#xff0c;你有个任务&#xff0c;你只希望他在单个节点执行&#xff0c;而不希望他并行执行&#xff0c;而且这个任务是支持重复执行的。如对某…

Lock和Rlock

Lock.acquire([blocking]) 获取一把锁&#xff0c;阻塞的或者非阻塞的。 当调用时blocking参数设置为True&#xff08;默认值&#xff09;&#xff0c;将阻塞直至锁变成unblocked&#xff0c;然后设置它的状态为locked并返回True。 当调用时blocking参数设置为False&#xff0…

什么是锁(Lock)

在并发编程中&#xff0c;锁&#xff08;Lock&#xff09;是一种用于控制对共享资源的访问的机制。它可以确保在某个时刻只有一个线程可以访问被锁定的资源&#xff0c;从而保证了数据的一致性和线程安全性。 锁通常用于解决多线程并发访问共享资源时可能出现的数据竞争和不一…