Laravel  
laravel
文档
数据库
架构
入门
php技术
    
Laravelphp
laravel / php / java / vue / mysql / linux / python / javascript / html / css / c++ / c#

java自旋锁

作者:蓝梦月影   发布日期:2025-04-22   浏览:110

import java.util.concurrent.atomic.AtomicReference;

public class SpinLock {
    private final AtomicReference<Thread> owner = new AtomicReference<>();

    // 尝试获取锁
    public void lock() {
        Thread current = Thread.currentThread();
        while (!owner.compareAndSet(null, current)) {
            // 自旋等待,直到获取到锁
        }
    }

    // 释放锁
    public void unlock() {
        Thread current = Thread.currentThread();
        if (!owner.compareAndSet(current, null)) {
            throw new IllegalStateException("Calling thread has not held the lock");
        }
    }

    public static void main(String[] args) {
        SpinLock spinLock = new SpinLock();

        // 模拟两个线程竞争锁
        Runnable task = () -> {
            System.out.println(Thread.currentThread().getName() + " trying to acquire lock.");
            spinLock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " acquired lock.");
                // 执行临界区代码
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(Thread.currentThread().getName() + " releasing lock.");
                spinLock.unlock();
            }
        };

        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");

        t1.start();
        t2.start();
    }
}

解释说明

  1. 自旋锁的实现

    • 使用 AtomicReference<Thread> 来存储当前持有锁的线程。
    • lock() 方法中,使用 compareAndSet 方法尝试将 owner 设置为当前线程。如果设置成功,则表示获取到了锁;否则,线程会继续自旋(即循环)等待,直到获取到锁。
  2. 解锁操作

    • unlock() 方法中,确保只有当前持有锁的线程才能释放锁。如果当前线程不是持有锁的线程,则抛出异常。
  3. 示例代码

    • main 方法中,创建了两个线程 t1t2,它们都尝试获取同一个自旋锁。
    • 当一个线程获取到锁后,另一个线程会自旋等待,直到第一个线程释放锁。
    • 这样可以保证同一时间只有一个线程能够进入临界区执行代码。

注意事项

  • 自旋锁适用于锁的竞争不激烈且持有锁的时间较短的场景。如果锁竞争激烈或持有锁的时间较长,自旋锁会导致大量的 CPU 资源浪费。

上一篇:java string 长度

下一篇:java重载和重写的区别

大家都在看

java连接数据库的代码

ubuntu 卸载java

java sort用法

java collections.sort

java file类的方法

java 判断

java时间数据类型

java 时间加一天

java demo

java 截取

Laravel PHP 深圳智简公司。版权所有©2023-2043 LaravelPHP 粤ICP备2021048745号-3

Laravel 中文站