`

自旋锁以及可重入自旋锁

 
阅读更多

首先是简单的自旋锁代码实现:

package org.cc.concur;

public class MyLock {

	public MyLock() {
	}
	
	private boolean isLocked=false;
	public  synchronized void lock() throws InterruptedException{
		while(isLocked){
			System.out.println(Thread.currentThread().getName()+"堵塞了");
			wait();
		}
		isLocked=true;
		System.out.println(Thread.currentThread().getName()+"正在运行");
		Thread.currentThread().sleep(1000);
	}
	
	public synchronized void unlock(){
		isLocked=false;
		notifyAll();
	}
	
	
}

 这是一个最简单的自旋锁

有如下特点:

  • 不支持重入
  • 任一非锁定线程执行unlock都会导致锁失效(这个是操作相关的)

以上的特点用如下代码来测试:

  // 正常使用情况

	public void testLock() throws InterruptedException{
		final MyLock lock=new MyLock();
		Thread thread=new Thread(new Runnable(){
			@Override
			public void run(){
				try{
				lock.lock();
				System.out.println("-------1线程正在运行");
				Thread.sleep(1000);
				System.out.println("-------1线程运行结束。。。。。。");
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					lock.unlock();
				}
			}
		}, "线程2");
		thread.start();
		lock.lock();
		System.out.println("-------主线程正在运行");
		Thread.sleep(1000);
		System.out.println("-------主线程运行结束。。。。。。");
		lock.unlock();
	}

 输出:

main正在运行
-------主线程正在运行
线程1堵塞了
-------主线程运行结束。。。。。。
线程1正在运行

 

// 非锁定线程使用了unlock

		Thread thread=new Thread(new Runnable(){
			@Override
			public void run(){
				try{
				lock.unlock();
				lock.lock();
				System.out.println("-------1线程正在运行");
				Thread.sleep(1000);
				System.out.println("-------1线程运行结束。。。。。。");
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					lock.unlock();
				}
			}
		}, "线程1");

 这样可以看出 任何的非锁定线程的线程都可以解开锁

main正在运行
-------主线程正在运行
线程1正在运行
-------主线程运行结束。。。。。。
-------1线程正在运行

 最后一种就是重入的情况:

		lock.lock();
		lock.lock();
		System.out.println("-------主线程正在运行");
		Thread.sleep(1000);
		System.out.println("-------主线程运行结束。。。。。。");
		lock.unlock();

 输出:

main正在运行
main堵塞了
线程1堵塞了

 

 

以上的地方改进很简单

设置一个属性保存进入的线程对象  并进行一些判断

以上一些缺点共同写入了代码:

package org.cc.concur;

public class MyLockReentranceLock {

	public MyLockReentranceLock() {
	}
	
	private boolean isLocked=false;
	private int count=0;
	private Object currentThread=null;
	
	public  synchronized void lock() throws InterruptedException{
				
		while(isLocked&&Thread.currentThread()!=currentThread){
			System.out.println(Thread.currentThread().getName()+"堵塞了");
			wait();
		}
		
		currentThread=Thread.currentThread();
		
		if(count==0){
		isLocked=true;
		}
		
		count++;
		System.out.println(Thread.currentThread().getName()+"正在运行");
		Thread.sleep(1000);
	}
	
	public synchronized void unlock(){
		if(Thread.currentThread()==currentThread){
		  count--;
		  System.out.println("---状态:"+Thread.currentThread().getName()+": "+count);
		}
		if(count==0){
		 isLocked=false;
		 currentThread=null;
		 System.out.println(Thread.currentThread().getName()+"-----解放了锁");
		 notifyAll();
		}			
	}
	
	public static void main(String []args) throws InterruptedException{
		final MyLockReentranceLock lock=new MyLockReentranceLock();  // 支持重入
		Thread thread=new Thread(new Runnable(){
			@Override
			public void run(){
				try{
				lock.lock();
				System.out.println("-------1线程正在运行");
				Thread.sleep(1000);
				System.out.println("-------1线程运行结束。。。。。。");
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					lock.unlock();
				}
			}
		}, "线程1");
		
		Thread thread2=new Thread(new Runnable(){
			@Override
			public void run(){
				try{
				lock.unlock();
				lock.lock();
				System.out.println("-------2线程正在运行");
				Thread.sleep(1000);
				System.out.println("-------2线程运行结束。。。。。。");
				
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					lock.unlock();
				}
			}
		}, "线程2");
		
		thread2.start();
		thread.start();
		
		lock.lock();
		lock.lock();  
		System.out.println("主线程正在运行。。。。。");
		Thread.sleep(1000);
		System.out.println("主线程运行结束。。。。。。");
		lock.unlock();
		lock.unlock();
	}
	

}

 一次运行时的情况:

main正在运行
main正在运行
主线程正在运行。。。。。
线程1堵塞了
线程2堵塞了
主线程运行结束。。。。。。
---状态:main: 1
---状态:main: 0
main-----解放了锁
线程2正在运行
-------2线程正在运行
线程1堵塞了
-------2线程运行结束。。。。。。
---状态:线程2: 0
线程2-----解放了锁
线程1正在运行
-------1线程正在运行
-------1线程运行结束。。。。。。
---状态:线程1: 0
线程1-----解放了锁

 

分享到:
评论

相关推荐

    基于SMP的Linux内核自旋锁分析.pdf

    "基于SMP的Linux内核自旋锁分析" 本文将对基于SMP(Symmetrical Multi-Processing)的Linux内核自旋锁进行分析。自旋锁是一种常用的并发机制,用于解决多处理器系统中的并发执行问题。在Linux内核中,自旋锁是实现...

    信号量、互斥体和自旋锁的区别

    ### 信号量、互斥体和自旋锁的区别详解 #### 一、基本概念与应用场景 **信号量**、**互斥体**和**自旋锁**是操作系统中三种常用的同步机制,主要用于解决多线程或多进程环境中资源的并发访问问题。这三种机制虽然...

    无锁编程之自旋锁的C++实现

    队列锁则提供了更好的可扩展性,适用于更多线程的情况。 总的来说,无锁编程和自旋锁在高性能并发系统中具有重要意义,它们可以帮助我们构建高效、低延迟的多线程程序。通过学习这些C++实现,我们可以更好地理解和...

    Windows驱动编程视频教程 提升IRQ与自旋锁

    在Windows驱动程序开发中,理解和掌握中断请求级别(IRQ)以及自旋锁是至关重要的。本视频教程将深入探讨这两个核心概念,旨在帮助开发者提升驱动程序的性能和稳定性。 首先,我们来了解一下中断请求级别(IRQ)。...

    信号量与自旋锁

    本文将深入探讨两种常见的同步机制——信号量和自旋锁,它们在Linux内核中的应用以及如何有效地使用它们。 #### 一、信号量:睡眠锁机制 **信号量**是一种广泛使用的同步机制,用于控制多个进程对共享资源的访问。...

    Linux系统内核的同步机制-自旋锁

    在单CPU且不可抢占的内核中,自旋锁的操作会简化为无操作,但在多CPU或可抢占的环境中,自旋锁就显得尤为重要。 Linux内核提供了多种自旋锁的API,例如: 1. `spin_lock_init(x)`:初始化自旋锁x。 2. `DEFINE_...

    自旋锁操作 spin_lock

    在分析 `spin_lock.c` 示例程序时,我们会看到如何在实际代码中使用这些自旋锁函数,以及如何正确地进行同步操作。通过运行和调试这个程序,我们可以更好地理解自旋锁的工作原理及其在多线程环境中的应用。 总之,...

    Java并发篇乐观锁,悲观锁,自旋锁

    本文主要讨论了四种锁类型:乐观锁、悲观锁、自旋锁以及Java中的synchronized同步锁,并深入解析了synchronized锁的内部机制,包括其核心组件、实现方式以及锁的状态。 1. **乐观锁**:乐观锁假设在多线程环境下,...

    SQL server 自旋锁争用专题

    自旋锁争用的症状通常表现为数据库系统响应缓慢,CPU使用率异常高,以及事务执行时间增长。当多个并发进程争夺同一资源时,系统可能会长时间地将CPU时间浪费在等待锁的释放上,而不是进行有效的数据处理。 在自旋锁...

    一种Linux内核自旋锁死锁检测机制的设计与实现.pdf

    Linux 内核自旋锁死锁检测机制设计与实现 在 Linux 内核中,自旋锁是一种广泛应用的锁机制,可以大幅提高系统性能和吞吐量。但是,自旋锁的使用不当,会立即将系统锁死,直至人工重启才能解锁,这是危害性最大的...

    linux系统中基于自旋锁的进程调度的实现

    本文将深入探讨Linux系统中基于自旋锁的进程调度实现,以及自旋锁、共享内存和汇编语言在其中的作用。 自旋锁(Spinlock)是一种简单的互斥机制。当一个进程持有一个自旋锁时,其他试图获取该锁的进程将进入“自旋...

    深入讲解我们说的CAS自旋锁到底是什么

    深入讲解CAS自旋锁的实现机理和原理 CAS(Compare and Swap)是实现自旋锁或乐观锁的核心操作,它的出现是为了解决原子操作的问题。在多线程环境下,原子操作是保证线程安全的重要手段。CAS操作的实现很简单,就是...

    golang实现Redis分布式自旋锁+本地自旋锁

    在Golang中,实现分布式自旋锁和本地自旋锁是一种常见的并发控制策略,用于解决多线程或分布式系统中的资源竞争问题。自旋锁的基本思想是,当一个线程试图获取锁时,如果锁已被其他线程持有,它会不断地检查锁的状态...

    redis实现分布式锁,自旋式加锁,lua原子性解锁

    本文将深入探讨如何使用Redis实现分布式锁,以及如何利用自旋式加锁和Lua脚本实现原子性解锁。 首先,我们来理解分布式锁的基本概念。分布式锁是在多节点之间共享资源时,用于协调各个节点的访问控制机制。在分布式...

    自旋锁公平性的三种实现代码下载

    - 线程自旋等待的逻辑:如何避免无休止地自旋,以及何时停止自旋尝试获取锁。 - 公平策略的实现:如何保证线程按照请求的顺序获取锁。 - 内存同步原语的使用:如CAS(Compare And Swap)操作,用于无锁编程。 - 锁的...

    linux下自旋锁程序源码.zip

    这些示例可能涵盖了自旋锁的基本使用、在中断处理中的应用以及可能的优化技巧。通过阅读和理解这些源码,开发者可以深入学习自旋锁的工作原理和最佳实践。 总结来说,Linux下的自旋锁是内核同步的重要工具,主要...

    并发控制之自旋锁.pdf

    自旋锁的设计理念是,在等待锁释放的过程中,持有锁的任务会不断地检查锁的状态,即“自旋”,直到锁变为可用状态。这种方式在锁的持有时间极短的情况下是非常高效的,因为减少了上下文切换的开销。然而,如果锁被长...

    java 中的锁 - 偏向锁、轻量级锁、自旋锁、重量级锁

    java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

    zynq的linux驱动6-使用自旋锁实现竞争保护

    5. **自旋锁优化**:为了防止饥饿和提高效率,Linux内核提供了可剥夺自旋锁(`spin_lock_irqsave()`和`spin_unlock_irqrestore()`)和不可剥夺自旋锁(`spin_lock_bh()`和`spin_unlock_bh()`)。前者会禁用中断,后...

Global site tag (gtag.js) - Google Analytics