赞
踩
这是一个实用工具类,提供基本的线程阻塞原语,如park()和unpark(),用于创建自定义的同步机制。
类的方法如下:
使用场景主要包括以下几种:
示例:
import java.util.concurrent.locks.LockSupport; public class LockSupportExample { public static void main(String[] args) { Thread producer = new Thread(() -> { System.out.println("生产者开始生产..."); // 模拟生产数据 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("生产者生产完毕,准备唤醒消费者..."); LockSupport.unpark(consumer); // 唤醒消费者线程 }); Thread consumer = new Thread(() -> { System.out.println("消费者等待生产者生产..."); LockSupport.park(); // 阻塞消费者线程,等待生产者唤醒 System.out.println("消费者收到通知,开始消费..."); }); consumer.start(); // 先启动消费者线程 producer.start(); // 然后启动生产者线程 } }
在这个示例中,生产者线程在生产完数据后调用 LockSupport.unpark(consumer)
唤醒消费者线程,消费者线程在启动时调用 LockSupport.park()
将自己阻塞,等待生产者线程唤醒。
Lock接口的一个实现,它允许单个线程多次获得锁,是一个可重入的互斥锁。
类的方法如下:
isLocked(): boolean
- 返回此锁是否被线程持有。
lockInterruptibly(): void
- 获取锁,但如果线程在等待获取锁的过程中被中断,将抛出InterruptedException。
hasWaiters(Condition): boolean
- 返回给定条件的等待集中是否有任何等待的线程。
getWaitQueueLength(Condition): int
- 返回等待在给定条件的等待集中的线程数。
hasQueuedThreads(): boolean
- 返回是否有线程等待获取此锁。
hasQueuedThread(Thread): boolean
- 返回给定线程是否在等待获取此锁的队列中。
getHoldCount(): int
- 返回当前线程在此锁上重复获取的次数。
toString(): String
- 返回此锁的字符串表示形式。
getQueueLength(): int
- 返回等待获取此锁的线程数。
lock(): void
- 获取锁,如果锁不可用,使当前线程等待。
newCondition(): Condition
- 创建并返回一个新的Condition实例,该实例绑定到此锁。
isFair(): boolean
- 返回此锁是否为公平锁。
getWaitingThreads(Condition): Collection<Thread>
- 返回正在等待给定条件的线程。
tryLock(): boolean
- 尝试获取锁,仅在调用时锁是空闲的才获取锁。
getQueuedThreads(): Collection<Thread>
- 返回一个集合,它包含可能正在等待获取此锁的所有线程。
tryLock(long, TimeUnit): boolean
- 尝试在给定的等待时间内获取锁。
getOwner(): Thread
- 返回持有此锁的线程,如果没有线程持有则返回null。
unlock(): void
- 释放锁。
isHeldByCurrentThread(): boolean
- 返回当前线程是否持有此锁。
使用场景:
示例:
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockExample { private final ReentrantLock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); private int count = 0; public void increment() { lock.lock(); // 获取锁 try { count++; System.out.println("Count: " + count); condition.signalAll(); // 唤醒所有等待的线程 } finally { lock.unlock(); // 释放锁 } } public void decrement() { lock.lock(); // 获取锁 try { count--; System.out.println("Count: " + count); condition.signalAll(); // 唤醒所有等待的线程 } finally { lock.unlock(); // 释放锁 } } public void waitForZero() throws InterruptedException { lock.lock(); // 获取锁 try { while (count != 0) { condition.await(); // 等待直到 count 为 0 } System.out.println("Count is zero"); } finally { lock.unlock(); // 释放锁 } } public static void main(String[] args) { ReentrantLockExample example = new ReentrantLockExample(); Thread t1 = new Thread(() -> { for (int i = 0; i < 5; i++) { example.increment(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 5; i++) { example.decrement(); } }); Thread t3 = new Thread(() -> { try { example.waitForZero(); } catch (InterruptedException e) { e.printStackTrace(); } }); t1.start(); t2.start(); t3.start(); } }
在这个示例中,我们使用了 ReentrantLock 来保护对共享资源(count)的访问。我们创建了三个线程,分别执行递增、递减和等待计数器为零的操作。通过使用 ReentrantLock 和 Condition,我们可以确保在多线程环境下对这些操作的正确同步。
ReadWriteLock接口的一个实现,支持可重入的读锁和写锁功能。
类的方法如下:
getThreadId(Thread): long
- 获取指定线程的ID。getReadLockCount(): int
- 获取当前持有读锁的线程数量。getQueuedReaderThreads(): Collection<Thread>
- 返回等待获取读锁的线程集合。getQueuedThreads(): Collection<Thread>
- 返回等待获取任何锁(读或写)的线程集合。hasQueuedThreads(): boolean
- 是否有线程在等待获取锁。getWaitQueueLength(Condition): int
- 返回给定条件的等待队列中的线程数。writeLock(): WriteLock
- 获取写锁。getWriteHoldCount(): int
- 获取当前持有写锁的线程数量。hasWaiters(Condition): boolean
- 返回给定条件是否有等待的线程。getQueuedWriterThreads(): Collection<Thread>
- 返回等待获取写锁的线程集合。isWriteLockedByCurrentThread(): boolean
- 当前线程是否持有写锁。getWaitingThreads(Condition): Collection<Thread>
- 返回正在等待给定条件的线程集合。readLock(): ReadLock
- 获取读锁。getQueueLength(): int
- 返回等待获取任何锁(读或写)的线程数。toString(): String
- 返回此锁的字符串表示形式。hasQueuedThread(Thread): boolean
- 检查指定的线程是否在等待队列中。getOwner(): Thread
- 返回当前持有锁的线程,如果没有线程持有则返回null。isFair(): boolean
- 判断此锁是否为公平锁。isWriteLocked(): boolean
- 判断此锁是否被写锁定。getReadHoldCount(): int
- 获取当前持有读锁的线程数量。使用场景:
示例:
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReentrantReadWriteLockExample { private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private int count = 0; public void increment() { readWriteLock.writeLock().lock(); // 获取写锁 try { count++; System.out.println("Incremented count to: " + count); } finally { readWriteLock.writeLock().unlock(); // 释放写锁 } } public void decrement() { readWriteLock.writeLock().lock(); // 获取写锁 try { count--; System.out.println("Decremented count to: " + count); } finally { readWriteLock.writeLock().unlock(); // 释放写锁 } } public void getCount() { readWriteLock.readLock().lock(); // 获取读锁 try { System.out.println("Current count: " + count); } finally { readWriteLock.readLock().unlock(); // 释放读锁 } } public static void main(String[] args) { ReentrantReadWriteLockExample example = new ReentrantReadWriteLockExample(); Thread t1 = new Thread(() -> { for (int i = 0; i < 5; i++) { example.increment(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 5; i++) { example.decrement(); } }); Thread t3 = new Thread(() -> { for (int i = 0; i < 5; i++) { example.getCount(); } }); t1.start(); t2.start(); t3.start(); } }
在这个示例中,我们使用了 ReentrantReadWriteLock 来保护对共享资源(count)的访问。我们创建了三个线程,分别执行递增、递减和获取计数器值的操作。通过使用 ReentrantReadWriteLock,我们可以确保在多线程环境下对这些操作的正确同步。
一个乐观读锁的实现,它提供了一种通过戳记来控制读写访问的方法,可以有效处理高并发的数据访问。
类方法如下:
unlockWrite(long stamp)
: 释放写锁。readLockInterruptibly()
: 获取读锁,可中断。validate(long stamp)
: 验证给定的stamp是否有效。acquireWrite(boolean interruptible, long nanos)
: 尝试获取写锁,可以指定是否可中断以及等待时间。tryReadLock(long time, TimeUnit unit)
: 尝试在指定的时间内获取读锁。writeLock()
: 获取写锁。getReadLockCount(long stamp)
: 获取给定stamp对应的读锁计数。tryUnlockWrite()
: 尝试释放写锁,如果成功则返回true,否则返回false。tryIncReaderOverflow(long stamp)
: 尝试增加溢出计数器,如果成功则返回新的stamp,否则返回0。isReadLocked()
: 判断是否有线程持有读锁。tryWriteLock(long time, TimeUnit unit)
: 尝试在指定的时间内获取写锁。readObject(ObjectInputStream in)
: 从输入流中读取对象。getReadLockCount()
: 获取当前读锁计数。toString()
: 返回类的字符串表示形式。unstampedUnlockRead()
: 释放未标记的读锁。tryConvertToWriteLock(long stamp)
: 尝试将给定的stamp转换为写锁,如果成功则返回新的stamp,否则返回0。isWriteLocked()
: 判断是否有线程持有写锁。release(WNode node)
: 释放节点持有的锁。tryOptimisticRead()
: 尝试进行乐观读操作。writeLockInterruptibly()
: 获取写锁,可中断。cancelWaiter(WNode w, WNode next, boolean isShared)
: 取消等待队列中的节点。tryConvertToReadLock(long stamp)
: 尝试将给定的stamp转换为读锁,如果成功则返回新的stamp,否则返回0。tryConvertToOptimisticRead(long stamp)
: 尝试将给定的stamp转换为乐观读锁,如果成功则返回新的stamp,否则返回0。asReadWriteLock()
: 返回一个ReadWriteLock实例。tryUnlockRead()
: 尝试释放读锁,如果成功则返回true,否则返回false。asWriteLock()
: 返回一个Lock实例,用于写操作。tryDecReaderOverflow(long stamp)
: 尝试减少溢出计数器,如果成功则返回新的stamp,否则返回0。acquireRead(boolean interruptible, long nanos)
: 尝试在指定的时间内获取读锁。unstampedUnlockWrite()
: 释放未标记的写锁。unlockRead(long stamp)
: 释放给定stamp对应的读锁。asReadLock()
: 返回一个Lock实例,用于读操作。tryWriteLock()
: 尝试获取写锁。readLock()
: 获取读锁。unlock(long stamp)
: 释放给定stamp对应的锁。使用场景:
示例:
import java.util.concurrent.locks.StampedLock; public class StampedLockExample { private int x = 0; private final StampedLock stampedLock = new StampedLock(); public void increment() { long stamp = stampedLock.writeLock(); try { x++; } finally { stampedLock.unlockWrite(stamp); } } public int getX() { long stamp = stampedLock.tryOptimisticRead(); int currentX = x; if (!stampedLock.validate(stamp)) { stamp = stampedLock.readLock(); try { currentX = x; } finally { stampedLock.unlockRead(stamp); } } return currentX; } public static void main(String[] args) { StampedLockExample example = new StampedLockExample(); Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { example.increment(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { System.out.println("Current value of x: " + example.getX()); } }); t1.start(); t2.start(); } }
在这个示例中,我们使用了 StampedLock 来保护对共享资源(x)的访问。我们创建了两个线程,一个线程用于递增 x 的值,另一个线程用于获取 x 的当前值。通过使用 StampedLock,我们可以确保在多线程环境下对这些操作的正确同步。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。