Java锁怎么使用

发布时间:2022-06-14 13:56:19 作者:iii
来源:亿速云 阅读:166

Java锁怎么使用

在Java中,锁(Lock)是一种用于控制多个线程对共享资源访问的机制。通过使用锁,可以确保在同一时间只有一个线程能够访问共享资源,从而避免数据竞争和不一致性问题。Java提供了多种锁机制,包括内置的synchronized关键字和java.util.concurrent.locks包中的显式锁。

1. 使用synchronized关键字

synchronized是Java中最基本的锁机制,它可以用于方法或代码块,确保同一时间只有一个线程能够执行被锁定的代码。

1.1 同步方法

通过在方法声明中添加synchronized关键字,可以将整个方法锁定。当一个线程进入该方法时,其他线程必须等待该线程退出方法后才能进入。

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

1.2 同步代码块

synchronized也可以用于代码块,锁定特定的对象。这种方式比同步方法更灵活,因为它允许你只锁定需要同步的部分代码。

public class Counter {
    private int count = 0;
    private final Object lock = new Object();

    public void increment() {
        synchronized (lock) {
            count++;
        }
    }

    public int getCount() {
        synchronized (lock) {
            return count;
        }
    }
}

2. 使用ReentrantLock

ReentrantLockjava.util.concurrent.locks包中的一个显式锁实现。与synchronized相比,ReentrantLock提供了更多的功能,如可中断的锁获取、超时锁获取、公平锁等。

2.1 基本用法

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private int count = 0;
    private final Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();  // 获取锁
        try {
            count++;
        } finally {
            lock.unlock();  // 释放锁
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

2.2 可中断锁

ReentrantLock允许线程在等待锁的过程中被中断,这在某些情况下非常有用。

public void incrementInterruptibly() throws InterruptedException {
    lock.lockInterruptibly();  // 可中断的锁获取
    try {
        count++;
    } finally {
        lock.unlock();
    }
}

2.3 超时锁

ReentrantLock还支持超时锁获取,即线程在指定的时间内尝试获取锁,如果超时则放弃。

public boolean incrementWithTimeout(long timeout, TimeUnit unit) throws InterruptedException {
    if (lock.tryLock(timeout, unit)) {  // 尝试获取锁,超时则返回false
        try {
            count++;
            return true;
        } finally {
            lock.unlock();
        }
    }
    return false;
}

2.4 公平锁

ReentrantLock可以配置为公平锁,即按照线程请求锁的顺序来分配锁。默认情况下,ReentrantLock是非公平的。

private final Lock fairLock = new ReentrantLock(true);  // 公平锁

3. 使用ReadWriteLock

ReadWriteLock是一种特殊的锁,它允许多个读线程同时访问共享资源,但在写线程访问时,所有读线程和其他写线程都会被阻塞。ReentrantReadWriteLockReadWriteLock的一个实现。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SharedResource {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private int data = 0;

    public void readData() {
        rwLock.readLock().lock();
        try {
            System.out.println("Read data: " + data);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void writeData(int newData) {
        rwLock.writeLock().lock();
        try {
            data = newData;
            System.out.println("Write data: " + data);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

4. 使用StampedLock

StampedLock是Java 8引入的一种新的锁机制,它提供了更细粒度的锁控制,并且在某些场景下性能优于ReadWriteLock

import java.util.concurrent.locks.StampedLock;

public class SharedResource {
    private final StampedLock stampedLock = new StampedLock();
    private int data = 0;

    public void readData() {
        long stamp = stampedLock.tryOptimisticRead();
        int currentData = data;
        if (!stampedLock.validate(stamp)) {
            stamp = stampedLock.readLock();
            try {
                currentData = data;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        System.out.println("Read data: " + currentData);
    }

    public void writeData(int newData) {
        long stamp = stampedLock.writeLock();
        try {
            data = newData;
            System.out.println("Write data: " + data);
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
}

5. 总结

Java提供了多种锁机制来满足不同的并发需求。synchronized是最简单的锁机制,适用于大多数场景。ReentrantLock提供了更多的功能和灵活性,适用于需要更复杂控制的场景。ReadWriteLockStampedLock则适用于读多写少的场景,能够提高并发性能。

在选择锁机制时,应根据具体的应用场景和需求来决定使用哪种锁。合理使用锁可以有效地避免并发问题,提高程序的性能和稳定性。

推荐阅读:
  1. 如何实现Java锁升级
  2. Java怎么使用锁解决银行取钱问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:mysql触发器的概念是什么

下一篇:python正则表达式re模块怎么使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》