`
annan211
  • 浏览: 456547 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java锁的种类以及辨析(一):自旋锁

 
阅读更多
Java的多线程安全是基于Lock机制(或者隐式锁synchronized)实现的,而Lock的性能往往不如人意。

原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的。
互斥是一种会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源的操作。

为了优化Java的Lock机制,从Java6开始引入了轻量级锁的概念。

轻量级锁(Lightweight Locking)本意是为了减少多线程进入互斥的几率,并不是要替代互斥。
它利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救。

这里先介绍第一种轻量级锁  自旋锁

自旋锁的原理是 让其他线程不断的循环等待着去用自身线程引用去加锁(当锁的竞争不大且,锁的时间段比较长的时候适用)

使用  AtomicReference 的方法 compareAndSet(V expect, V update):如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。

代码如下:
  class SpinLock {

	private AtomicReference<Thread> sign = new AtomicReference<Thread>();

	public void lock() {
		Thread current = Thread.currentThread();
		//System.out.println(Thread.currentThread().getName() + " wait");
		while (!sign.compareAndSet(null, current)) {

		}
	}

	public void unlock() {
		Thread current = Thread.currentThread();
		sign.compareAndSet(current, null);
	}
}


实例如下:

  package thread;

import java.util.concurrent.atomic.AtomicReference;

public class SpinLockTest {
	private static int count = 0;
	private static SpinLock spinLock = new SpinLock();
	/**
	 * @param args
	 */
	@SuppressWarnings("static-access")
	public static void main(String[] args) {

		for (int i = 0; i < 100000; i++) {
			Thread thread = new Thread(new Runnable(){
				@Override
				public void run() {
					spinLock.lock();
					count++;
					spinLock.unlock();
				}
			});
			thread.start();
		}
		System.out.println("here");
		try {
			Thread.currentThread().sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(count);
	}
}
/**
 * 自旋锁 让其他线程不断的循环等待着去用自身线程引用去加锁(当锁的竞争不大且,锁的时间段比较长的时候适用)。
 */
class SpinLock {

	private AtomicReference<Thread> sign = new AtomicReference<Thread>();

	public void lock() {
		Thread current = Thread.currentThread();
		//System.out.println(Thread.currentThread().getName() + " wait");
		while (!sign.compareAndSet(null, current)) {

		}
	}

	public void unlock() {
		Thread current = Thread.currentThread();
		sign.compareAndSet(current, null);
	}
}


稍微面向对象点  是这样子的
package thread;

import java.util.concurrent.atomic.AtomicReference;

public class SpinLockTest2 {

	static int count = 100;

	public static void main(String[] args) {
		final SplinLock lock = new SplinLock();
		for(int i=0;i<100;i++){
			new Thread(new ThreadDemo(lock)).start();
		}
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(count);
	}
}

class ThreadDemo implements Runnable{
	private SplinLock lock;
	public ThreadDemo(SplinLock lock){
		this.lock = lock;
	}
	@Override
	public void run() {
		lock.lock();
		System.out.println(Thread.currentThread().getName()+"---"+SpinLockTest2.count);
		SpinLockTest2.count--;
		lock.unlock();
	}
}


class SplinLock{

	private AtomicReference<Thread> reference = new AtomicReference<Thread>();

	public void lock(){
		Thread thread = Thread.currentThread();
		while(!reference.compareAndSet(null, thread)){

		}
	}

	public void unlock(){
		Thread thread = Thread.currentThread();
		reference.compareAndSet(thread, null);
	}

}
分享到:
评论

相关推荐

    C#多线程编程中的锁系统(四):自旋锁

    二:自旋锁示例 三:SpinLock 四:继续SpinLock 五:总结 一:基础 内核锁:基于内核对象构造的锁机制,就是通常说的内核构造模式。用户模式构造和内核模式构造  优点:cpu利用最大化。它发现资源被锁住,请求就...

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

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

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

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

    【量子力学】 第9章:自旋.pdf

    量子力学中的自旋概念是理解物质微观世界中粒子特性的一个重要方面。本章《自旋》深入探讨了电子自旋的本质、相关数学工具以及实验验证。 首先,自旋算符与Pauli矩阵是研究自旋系统的两个基础工具。自旋算符用于...

    自旋锁操作 spin_lock

    自旋锁的基本思想是当一个线程试图获取已被其他线程持有的锁时,它不会立即阻塞,而是不断地循环检查锁的状态,直到锁变为可用状态为止,这个过程称为“自旋”。在Linux内核中,自旋锁是实现内核级并发的重要工具。 ...

    全息术中物质的特征:自旋-轨道相互作用

    量规/引力对偶作为物质理论需要一种系统的方法来表征系统。 我们建议“批量提升”与本体理论最不相关的相互作用。 例如,我们考虑自旋-轨道相互作用,这会引起磁电相互作用项。 我们表明,它的举升是轴键耦合。 我们...

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

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

    Java轻量级锁(自旋锁)和偏向锁原理

    在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中为了减少获得锁和释放...

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

    Linux系统内核的同步机制是确保多线程和多处理器环境下正确访问共享资源的关键部分,其中自旋锁作为一项重要工具,被广泛用于保护短暂的、临界区的访问。自旋锁的设计理念在于,当一个线程尝试获取已被其他线程持有...

    自旋光电流与电流诱导的电子自旋极化——半导体自旋电子学的新进展.pdf

    1. 自旋光电流(Spin Photocurrent):自旋光电流是一种新的电子学现象,它通过自旋轨道耦合实现电子的自旋极化。在这种现象中,光子激发电子,产生自旋极化的电子流。 2. 电流诱导的电子自旋极化(Current-Induced...

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

    自旋锁是多线程编程中的一个重要概念,用于在共享资源上实现轻量级的同步。自旋锁的原理是当一个线程试图获取已被其他线程持有的锁时,它不会立即阻塞,而是会“自旋”等待,直到锁被释放为止。这样做的好处是可以...

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

    4. `5_queuelock.cpp`:队列锁(也称为自旋队列锁)是一种更复杂的自旋锁,它通过维护一个请求锁的线程队列来减少竞争。 5. `6_threadlocal.cpp`:可能涉及到线程局部存储,这种技术可以为每个线程提供独立的数据,...

    linux下自旋锁程序源码.zip

    自旋锁的原理是,当一个线程试图获取一个已经被其他线程持有的锁时,它不会像普通互斥锁那样进入睡眠状态,而是会不断地循环检查锁的状态,直至锁变为可用状态。这种机制在处理器等待时间短且锁持有时间也很短的情况...

    论文研究 - Co(001)/ Cu量子阱系统上的Co和酞菁覆盖层:自旋极化电子反射实验

    通过自旋极化电子反射研究了Co或酞菁(Pc)分子覆盖层对Co(001)顶部Cu层中量子阱共振(QWR)性质的影响。 对于Co原子和Pc分子,随着覆盖率的增加,观察到QWR诱导信号的能量转移,这归因于Cu / Co和Cu / Pc界面电子...

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

    当一个处理器尝试获取自旋锁时,如果该锁当前被另一个处理器占用,则该处理器将继续尝试获取该锁,直到获得访问权。 在SMP系统中,自旋锁的实现非常重要,因为它可以确保多个处理器之间的并发执行。为了实现自旋锁...

    spinlocks:各种自旋锁实现和基准测试

    本文将深入探讨自旋锁的实现机制、不同类型的自旋锁以及它们的基准测试。我们将以C语言作为实现和测试的基础,因为它是低级编程和系统编程的常用语言,能够更好地理解和控制底层细节。 1. **自旋锁基础** - **定义...

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

    在 Linux 内核中,自旋锁的种类有很多,包括基本型、读写自旋、排队锁和 MCS 自旋锁等。每种自旋锁都有其特点和使用场景,需要根据不同的情况选择合适的自旋锁。 在设计自旋锁死锁检测机制时,需要考虑到自旋锁的...

Global site tag (gtag.js) - Google Analytics