lock学习笔记01

深入解析Java中的synchronized关键字 接下来是偏向锁,我们还是用同样的代码即可,需要注意的是偏向锁必须在jvm启动后的一段时间才会运行,所以如果我们想打印偏向锁必须让线程休眠那么几秒,这里笔者就偷懒了一下,通过设置jvm参数。打印结果如下,我们只需关注第一行的object header,可以看到第一列的00000001,我们看到后3位为001,偏向锁标记为0,锁标记为01,001这就是我们说的无锁状态。上文讲解锁升级的之后,我们一直在说对象头的概念,所以为了能够直观的看到锁对象中对象头锁标记和锁状态的变化,我们这里引入一个jol工具。 阅读详情

一:为什么要学习lock,synchronized和lock的区别

此部分转载,原文链接已失效

请注意, Lock实例只是普通对象,它们本身可以用作synchronized语句中的目标。 获取Lock实例的监视器锁与调用该实例的任何lock()方法没有特定关系。 建议为避免混淆,不要以这种方式使用Lock实例。

1、synchronized和lock的用法区别

synchronized:在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。
 
lock:需要显示指定起始位置和终止位置。一般使用ReentrantLock类做为锁,多个线程中必须要使用一个ReentrantLock类做为对象才能保证锁的生效。且在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。
 
用法区别比较简单,这里不赘述了,如果不懂的可以看看Java基本语法。
 
2、synchronized和lock性能区别
 
synchronized是托管给JVM执行的,而lock是java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。

synchronized是托管给JVM执行的,所以在通知线程的时候是由虚拟机随机选择的(synchronized相当于整个lock对象只有一个单一的Condition对象,所有的线程等待、通知操作都由它完成,notifyall需要通知所有waitting线程),但是lock结合condition可以实现选择性通知(可以注册多个Condition,我们可以实现让每个Condition控制指定的一部分线程,这样一来,我们想选择性唤醒该部分线程,只需要调用控制那部分线程的Condition执行唤醒操作signalAll即可,其他线程仍保持waitting状态,这里涉及到condition的用法参考另一笔记,提一下signal与notify的区别,)
 
说到这里,还是想提一下这2中机制的具体区别。据我所知,synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。
 
而Lock用的是乐观锁方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制就是CAS操作(Compare and Swap)。我们可以进一步研究ReentrantLock的源代码,会发现其中比较重要的获得锁的一个方法是compareAndSetState。这里其实就是调用的CPU提供的特殊指令。
 
现代的CPU提供了指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。这个算法称作非阻塞算法,意思是一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。
 
我也只是了解到这一步,具体到CPU的算法如果感兴趣的读者还可以在查阅下,如果有更好的解释也可以给我留言,我也学习下。
 
3、synchronized和lock用途区别
 
synchronized原语和ReentrantLock在一般情况下没有什么区别,但是在非常复杂的同步应用中,请考虑使用ReentrantLock,特别是遇到下面2种需求的时候。
 
3.1.某个线程在等待一个锁的控制权的这段时间需要中断
3.2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
3.3.具有公平锁功能,每个到来的线程都将排队等候
 
先说第一种情况,ReentrantLock的lock机制有2种,忽略中断锁和响应中断锁,这给我们带来了很大的灵活性。比如:如果A、B2个线程去竞争锁,A线程得到了锁,B线程等待,但是A线程这个时候实在有太多事情要处理,就是一直不返回,B线程可能就会等不及了,想中断自己,不再等待这个锁了,转而处理其他事情。这个时候ReentrantLock就提供了2种机制,第一,B线程中断自己(或者别的线程中断它),但是ReentrantLock不去响应,继续让B线程等待,你再怎么中断,我全当耳边风(synchronized原语就是如此);第二,B线程中断自己(或者别的线程中断它),ReentrantLock处理了这个中断,并且不再等待这个锁的到来,完全放弃。

这里来做个试验,首先搞一个Buffer类,它有读操作和写操作,为了不读到脏数据,写和读都需要加锁,我们先用synchronized原语来加锁,如下:

 	public class Buffer {   
 	 
 	    private Object lock;   
 	 
	    public Buffer() {
	        lock = this;
 	    }   
 	 
 	    public void write() {
 	        synchronized (lock) {
 	            long startTime = System.currentTimeMillis();
 	            System.out.println("开始往这个buff写入数据…");
 	            for (;;)// 模拟要处理很长时间
 	            {
 	                if (System.currentTimeMillis()
 	                        - startTime > Integer.MAX_VALUE)
 	                    break;
	            }
 	            System.out.println("终于写完了");
 	        }
 	    }   
 	 
 	    public void read() {
 	        synchronized (lock) {
 	            System.out.println("从这个buff读数据");
 	        }
 	    }
 	}

接着,我们来定义2个线程,一个线程去写,一个线程去读。

 	public class Writer extends Thread {   
 	 
 	    private Buffer buff;   
 	 
 	    public Writer(Buffer buff) {
 	        this.buff = buff;
 	    }   
 	 
 	    @Override
 	    public void run() {
 	        buff.write();
 	    }   
 	 
 	}   
	 
	public class Reader extends Thread {   
 	 
 	    private Buffer buff;   
 	 
 	    public Reader(Buffer buff) {
	        this.buff = buff;
	    }   
 	 
	    @Override
 	    public void run() {   
	 
	        buff.read();//这里估计会一直阻塞   
	 
 	        System.out.println("读结束");   
 	 
	    }   
	 
 	}

好了,写一个Main来试验下,我们有意先去“写”,然后让“读”等待,“写”的时间是无穷的,就看“读”能不能放弃了。

 	public class Test {
 	    public static void main(String[] args) {
 	        Buffer buff = new Buffer();   
 	 
 	        final Writer writer = new Writer(buff);
 	        final Reader reader = new Reader(buff);   
 	 
 	        writer.start();
 	        reader.start();   
 	 
 	        new Thread(new Runnable() {   
 	 
 	            @Override
 	            public void run() {
 	                long start = System.currentTimeMillis();
 	                for (;;) {
 	                    //等5秒钟去中断读
 	                    if (System.currentTimeMillis()
	                            - start > 5000) {
 	                        System.out.println("不等了,尝试中断");
 	                        reader.interrupt();
 	                        break;
 	                    }   
 	 
 	                }   
 	 
 	            }
 	        }).start();   
 	 
	    }
 	}

我们期待“读”这个线程能退出等待锁,可是事与愿违,一旦读这个线程发现自己得不到锁,就一直开始等待了,就算它等死,也得不到锁,因为写线程要21亿秒才能完成 T_T ,即使我们中断它,它都不来响应下,看来真的要等死了。这个时候,ReentrantLock给了一种机制让我们来响应中断,让“读”能伸能屈,勇敢放弃对这个锁的等待。我们来改写Buffer这个类,就叫BufferInterruptibly吧,可中断缓存。

import java.util.concurrent.locks.ReentrantLock;

public class BufferInterruptibly {

	private ReentrantLock lock = new ReentrantLock();

	public void write() {
		lock.lock();
		try {
			long startTime = System.currentTimeMillis();
			System.out.println("开始往这个buff写入数据…");
			for (; ; )// 模拟要处理很长时间
			{
				if (System.currentTimeMillis()
						- startTime > Integer.MAX_VALUE)
					break;
			}
			System.out.println("终于写完了");
		} finally {
			lock.unlock();
		}
	}

	public void read() throws InterruptedException {
		lock.lockInterruptibly();// 注意这里,可以响应中断
		try {
			System.out.println("从这个buff读数据");
		} finally {
			lock.unlock();
		}
	}

}

当然,要对reader和writer做响应的修改

class Reader extends Thread {

	private BufferInterruptibly buff;

	public Reader(BufferInterruptibly buff) {
		this.buff = buff;
	}

	@Override
	public void run() {

		try {
			buff.read();//可以收到中断的异常,从而有效退出
		} catch (InterruptedException e) {
			System.out.println("我不读了");
		}

		System.out.println("读结束");

	}

}

/**
 * Writer倒不用怎么改动
 */
class Writer extends Thread {

	private BufferInterruptibly buff;

	public Writer(BufferInterruptibly buff) {
		this.buff = buff;
	}

	@Override
	public void run() {
		buff.write();
	}

}

class Test {
	public static void main(String[] args) {
		BufferInterruptibly buff = new BufferInterruptibly();

		final Writer writer = new Writer(buff);
		final Reader reader = new Reader(buff);

		writer.start();
		reader.start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				long start = System.currentTimeMillis();
				for (; ; ) {
					if (System.currentTimeMillis()
							- start > 5000) {
						System.out.println("不等了,尝试中断");
						reader.interrupt();
						break;
					}

				}

			}
		}).start();

	}
}

这次“读”线程接收到了lock.lockInterruptibly()中断,并且有效处理了这个“异常”。

至于第二种情况,ReentrantLock可以与Condition的配合使用,Condition为ReentrantLock锁的等待和释放提供控制逻辑。
 例如,使用ReentrantLock加锁之后,可以通过它自身的Condition.await()方法释放该锁,线程在此等待Condition.signal()方法,然后继续执行下去。await方法需要放在while循环中,因此,在不同线程之间实现并发控制,还需要一个volatile的变量(synchronized关键字具有volatile的使变量在多线程间可视化功能,所以不需要),boolean是原子性的变量。因此,一般的并发控制的操作逻辑如下所示:

	volatile boolean isProcess = false;
	ReentrantLock lock  = new ReentrantLock();
 	Condtion processReady = lock.newCondtion();
	thread: run() {
 	    lock.lock();
	    isProcess = true;
	   try {
	    while(!isProcessReady) {  //isProcessReady 是另外一个线程的控制变量
	      processReady.await();//释放了lock,在此等待signal
 	     }catch (InterruptedException e) {
 	          Thread.currentThread().interrupt();
 	        } finally {
	          lock.unlock();
 	          isProcess = false;
	        }
 	      }
 	    }
 	}

这里只是代码使用的一段简化,下面我们看Hadoop的一段摘取的源码:

 	private class MapOutputBuffer<K extends Object, V extends Object>
 	      implements MapOutputCollector<K, V>, IndexedSortable {
 	...
 	    boolean spillInProgress;
 	    final ReentrantLock spillLock = new ReentrantLock();
 	    final Condition spillDone = spillLock.newCondition();
 	    final Condition spillReady = spillLock.newCondition();
 	    volatile boolean spillThreadRunning = false;
 	    final SpillThread spillThread = new SpillThread();
 	...
 	    public MapOutputBuffer(TaskUmbilicalProtocol umbilical, JobConf job,
 	                           TaskReporter reporter
 	                           ) throws IOException, ClassNotFoundException {
 	    ...
 	      spillInProgress = false;
 	      spillThread.setDaemon(true);
	      spillThread.setName("SpillThread");
 	      spillLock.lock();
 	      try {
	        spillThread.start();
 	        while (!spillThreadRunning) {
	          spillDone.await();
 	        }
	      } catch (InterruptedException e) {
	        throw new IOException("Spill thread failed to initialize", e);
 	      } finally {
 	        spillLock.unlock();
 	      }
 	    }
 	 
 	    protected class SpillThread extends Thread {
 	 
 	      @Override
 	      public void run() {
 	        spillLock.lock();
	        spillThreadRunning = true;
	        try {
 	          while (true) {
 	            spillDone.signal();
 	            while (!spillInProgress) {
	              spillReady.await();
 	            }
 	            try {
 	              spillLock.unlock();
	              sortAndSpill();
	            } catch (Throwable t) {
	              sortSpillException = t;
	            } finally {
	              spillLock.lock();
	              if (bufend < bufstart) {
 	                bufvoid = kvbuffer.length;
 	              }
 	              kvstart = kvend;
 	              bufstart = bufend;
 	              spillInProgress = false;
 	            }
	          }
	        } catch (InterruptedException e) {
	          Thread.currentThread().interrupt();
	        } finally {
	          spillLock.unlock();
 	          spillThreadRunning = false;
 	        }
 	      }
 	    }

代码中spillDone 就是 spillLock的一个newCondition()。调用spillDone.await()时可以释放spillLock锁,线程进入阻塞状态,而等待其他线程的 spillDone.signal()操作时,就会唤醒线程,重新持有spillLock锁。
 
这里可以看出,利用lock可以使我们多线程交互变得方便,而使用synchronized则无法做到这点。
 
最后呢,ReentrantLock这个类还提供了2种竞争锁的机制:公平锁和非公平锁。这2种机制的意思从字面上也能了解个大概:即对于多线程来说,公平锁会依赖线程进来的顺序,后进来的线程后获得锁。而非公平锁的意思就是后进来的锁也可以和前边等待锁的线程同时竞争锁资源。对于效率来讲,当然是非公平锁效率更高,因为公平锁还要判断是不是线程队列的第一个才会让线程获得锁。

Java synchronized(详细) 在Java中,`synchronized`关键字用于解决多线程并发访问共享资源时可能出现的线程安全问题。 阅读详情

相关推荐

Cursor Pro版保姆级开通教程:绕过7天试用,支付宝一步搞定(附地区报错解决方案)

本文详细介绍了Cursor Pro版的订阅流程,包括支付宝支付步骤和解决区域报错的实用方案。针对开发者常见的网络问题和云服务器配置需求,提供了从本地环境调整到云端部署的完整指南,帮助用户高效解锁Pro版的代码补全、私有代码库等核心功能。

weixin_28710999的博客 2112

10-锁(synchronized和Lock)

锁(synchronized和lock)

titanium的博客 3968

Day470&471.Netty概述&Netty高性能架构设计 -netty

Netty概述 一、原生 NIO 存在的问题 NIO 的类库和 API 繁杂,使用麻烦:需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。 需要具备其他的额外技能:要熟悉 Java 多线程编程,因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网络编程非常熟悉,才能编写出高质量的 NIO 程序。 开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等等。 JDK NIO

阿昌爱Java 1572

synchronized 和 Lock详解总结

1 synchronized 和 Lock的区别 a)存在层次 synchronized是关键字,在jvm层面上,由内置语言实现。 Lock是接口、类。 b) 锁的释放 synchronized在线...

闫兆昌的博客 6391

从零到一:手把手教你用Verilog在FPGA上构建自己的FFT处理器(不依赖IP核)

本文详细介绍了如何从零开始使用Verilog在FPGA上构建256点FFT处理器,不依赖商业IP核。内容涵盖FFT算法基础、蝶形运算单元设计、整体架构实现、时序收敛优化策略以及测试验证方法,重点提升FPGA上算法部署的运行效率与资源利用率。

vv45678的博客 823

基于扩展卡尔曼滤波(EKF)结合到达时间(TDOA)、到达频率(FDOA)实现多无人机无源定位,MATLAB代码

该程序实现了一种结合到达时间差(TDOA)和到达频率差(FDOA)技术的多无人机定位方法,利用扩展卡尔曼滤波(EKF)对单一目标进行定位。程序通过模拟多无人机的运动及其与目标的相对位置,估计目标的状态(位置和速度)。

985工科博士毕业,专攻定位、导航和滤波等算法研究。从业10年,主要使用MATLAB 1267

一文带你彻底了解synchronized 和 Lock

synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。的时候,是会消耗CPU资源的。所以自旋必须要有一定的条件控制,否则如果一个线程执行同步代码块的时间很长,那么等待锁的线程会不断的循环反而会消耗CPU资源。在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要。在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。...

zhiyikeji的博客 3130

基于因果推理的LLM去毒:精准定位注意力头实现高效干预

在大型语言模型(LLM)的部署与应用中,模型安全与可控性是核心挑战之一。传统方法如全参数微调成本高昂,且可能损害模型通用能力。本文聚焦于一种基于因果推理的精准干预技术,其原理在于利用因果发现算法定位Transformer模型中与“毒性”输出存在强因果关联的特定注意力头。该技术通过分析注意力头的激活模式与生成文本毒性分数之间的因果关系,识别出关键责任单元,而非依赖传统的相关性分析。其技术价值在于实现了轻量级、高可解释性的模型行为修正,能以极低的参数改动代价有效降低模型在敏感话题上的有害输出。在应用场景上,该方

weixin_32667439的博客 315

JUC学习笔记——01. 线程, 进程和Lock锁

1. 什么是JUC JUC就是java.util.concurrent下面的类包,专门用于多线程的开发。 2. 线程和进程 1. 概念 进程: 运行的程序, 一个线程往往可以包含多个线程 java默认有两个线程: main线程和GC线程 线程 2. 并发和并行 并发: 多个线程操作同一资源 CPU一核, 快速交替, 模拟出来多条线程, 并行: 多个线程同时执行 CPU多核, 多个线程同时执行 3. 线程的多个状态 源码 public enum State { // 新生

bingque6535的博客 241

大数据安全 | 期末复习(上)| 补档

大数据定义:无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

知识库搭建ing 2590

Unity 多渠道分包工程化实践(大白话版):从“手工打包”到“一键出 30 个包还不翻车”

Unity多渠道分包工程化实践摘要(150字) 本文系统探讨Unity多渠道包自动化构建方案,提出基于BuildPipeline的工程化体系。核心包括:1)通过ScriptableObject/JSON管理渠道参数(包名、签名、SDK配置等);2)结合命令行与环境变量实现CI集成;3)开发通用Builder脚本支持资源动态替换与参数注入。重点分享了Android渠道包的签名配置、图标自动替换、宏定义注入等关键技术实现,并给出Jenkins流水线集成案例。该方案可支持日均数百个渠道包的自动化构建,显著提升分发

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 276

JUC学习笔记-01-Synchronized 与Lock 的区别

synchronized与lock锁的区别 来源: lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现; 异常是否释放锁 synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。) 是否中断等待 lock等待锁过程中可以用interr

小小学渣的博客 252

Dify智能体开发:大语言模型(LLM)问题分类

通过定义分类描述,问题分类器能够根据用户输入,使用 LLM 推理与之相匹配的分类并输出分类结果,向下游节点提供更加精确的信息。

王国平的博客 2253

01Lock锁

线程:对于Java而言,Thread 、Runnable、CallableJava是开启不了线程的,需要调用本地C++的方法启动硬件来开启线程。并发:多线程操作同一个资源(CPU单核) 并行:多条任务一起行走(CPU多核)获取CPU核数 并发编程本质:要充分利用CPU资源处理任务sleep与wait的区别以多线程卖票为例: 不难看出,多线程卖票在不加锁的情况下操作统一资源很容易出错。 解决1:传统解决方法是在同步代码中加入Sychronized锁:...

niannujiao6的博客 694

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JUC-01-Lock锁

线程的状态 public enum State { // 新建 NEW, // 运行 RUNNABLE, // 阻塞 BLOCKED, // 等待 WAITING, // 超时等待 TIMED_WAITING, // 终止 TERMINATED; } Lock锁 传统的Synchronized

六道 270

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【Python Threading 学习笔记】6、锁lock

往期内容: 1、什么是多线程? 2、添加线程 3、join功能 4、Queue功能 5、不一定有效率GIL 0x00 关于线程锁lock 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。 而使用l...

TeamsSix 的 优快云 空间 307

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

JUC学习笔记01

本人学习JUC的总结

qq_39203889的博客 1399

exclusive 和 lock

exclusive 和lock 1. 首先,Lock在amba2.0中就有涉及,意思是,某个master 可以通过Lock 总线来实现独占。只有当该master完成传输后才释放出总线。这样的话,总线的效率会降低。 2. 相比Lock,AXI 中引入了exclusive操作,不需要将bus锁定给某个master。而是通过TAG ID以及slave 返回的response来判断当前的传输是否成功。过程...

fgupupup的博客 4735

STM32 HAL_LOCK问题

STM32 HAL_LOCK问题 STM32 HAL_LOCK问题 在使用STM32的HAL库开发时候,在使用UART和CAN的使用,偶尔会碰到突然不再接收数据的情况.调试发现,信号有的,但是就是软件不再进入接收中断了. 通过调试,最后定位到问题点在于__HAL_LOCK()这个函数里. 以下用uart为例子,剖析这个问题. 典型的uart接收数据例子 uart配置后,最后调用一下 HAL_UAR...

m0_47132384的博客 8054

【JUC-01】JUC—lock接口及AQS核心知识讲解

1. lock接口 Lock接口作为锁的基础接口,具有锁基本功能,下面针对于源码分析一些基本的用法: public interface Lock { /** * 获取锁 * 调用该方法的当前线程将会获取锁,当锁获得之后,从该方法返回 */ void lock(); /** * 可中断的获取锁 * 和lock()方法不同之...

大黄奔跑 1059

【Java多线程】3——Lock API控制多线程

在实际场景中,读操作不会改变数据,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。针对这种场景,Java 的并发包提供了读写锁,它表示两个锁,一个是读操作相关的锁,称为读锁,这是一种共享锁;一个是写相关的锁,称为写锁,这是一种排他锁,也叫独占锁、互斥锁。

一棵灬大树的博客 1106

C++多线程学习07 unique_lock与scoped_lock

补充一个关键字noexcept noexcept形如其名地,表示其修饰的函数不会抛出异常。不过与throw()动态异常声明不同的是,在C++11中如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行,这比基于异常机制的throw()在效率上会高一些。这是因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等。 unique_lock与lock_guard()一样

qq_42567607的博客 1574

详解JDK锁01:结合源码一文弄懂Lock接口!

结合经典并发书籍《Java并发编程艺术》以及JDK源码,尽可能将JDK锁解释清楚!

周三不Coding的博客 388

多线程(八)Lock

前面我们可以使用synchronized关键字来实现线程之间的同步互斥,,同样是解决线程安全性问题的另一种解决方案,而且它更强大,更灵活本片博客介绍对其展开介绍;

mf97532的博客 1872

【Java开发】JUC进阶 01:Lock锁详解

本文主要介绍Lock锁、公平锁和非公平锁、Condition 精准通知和唤醒线程

尹煜的博客 1012

mysql lock table row_MySQL:Innodb 让MDL LOCK和ROW LOCK 记录到errlog

本文是一个说明文档,主要是为MySQL和Innodb做了两个比较简单的输出功能用于便于大家学习这两种锁,其实这个方法也是我学习的时候用到的:MySQL 层 MDL LOCKInnodb 层ROW LOCK但是由于能力有限肯定有考虑不周的地方,请指出。参数名字gaopeng用于快速查找自己加入的参数标志。仅用于学习测试。一、新加入的参数和保留的参数mysql> show variables l...

weixin_35801916的博客 200
上一篇: lock学习笔记02
下一篇: 白话经典算法系列之七 堆与堆排序
MrMoving
博客等级 码龄10年 54粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值