`

java读写锁升级与降级、并会发现死锁。抛出异常

    博客分类:
  • java
 
阅读更多
package com.huawei.test;

import java.util.HashMap;
import java.util.Map;


public class SpinReadWriteLock {
private volatile Thread writeThread = null;
private volatile int writeCount = 0;
//标记已经获取读lock的线程想要获取写lock   但被阻止了(因各种原因)
private volatile Thread readRequestWriteLockingThread = null;
private volatile Map<Thread, Integer> readThread = new HashMap<>();
private Object read = new Object();

public void readLock() throws InterruptedException {
Thread current = Thread.currentThread();
synchronized (read) {
while (writeThread != null && writeThread != current) {
read.wait();
}
Integer readCount = readThread.get(current);
if (readCount == null) {
// 表示当前线程正在持有锁 对锁持有的次数+1
readCount = 0;
}
readCount++;
readThread.put(current, readCount);
}
}

public void readUnlock() {
synchronized (read) {
Thread current = Thread.currentThread();
Integer readCount = readThread.get(current);
if (readCount <= 1) {
readThread.remove(current);
read.notifyAll();
return;
}
readCount--;
readThread.put(current, readCount);
}
}

public void writeLock() throws InterruptedException, DeadLockException {

Thread current = Thread.currentThread();
synchronized (read) {
while ((writeThread != null && writeThread != current)
//写锁被别的线程持有
|| readThread.size() > 1
//或者有多余一个的读锁持者
|| (readThread.size()==1 && !readThread.containsKey(current))
//或者有一个读锁持有者   但不是自己
) {
if(readRequestWriteLockingThread != null && readRequestWriteLockingThread != current)
throw new DeadLockException();
readRequestWriteLockingThread = current;
read.wait();
}
writeThread = current;
writeCount++;
}
}

public void writeUnLock() {

Thread current = Thread.currentThread();
if(current != writeThread)
//
return ;
if (writeCount == 1) {

synchronized (read) {
writeCount = 0;
writeThread = null;
read.notifyAll();
return;
}
}
writeCount--;
}

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {

// new Thread(new Read()).start();
// new Thread(new Write()).start();
new Thread(new DeadReadWrite()).start();
}
}

public final static SpinReadWriteLock READ_WRITE_LOCK = new SpinReadWriteLock();
public static class Read implements Runnable{

@Override
public void run() {

try {

READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(100);

} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "获取到了放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}
public static class Write implements Runnable{

@Override
public void run() {

try {
System.out.println(Thread.currentThread().getName() + "准备获取写锁");
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(200);

} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
}

}
}
public static class ReadWrite implements Runnable{

@Override
public void run() {


try {

READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(20);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(20);

} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}

public static class DeadReadWrite implements Runnable{

@Override
public void run() {
try {

READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");
Thread.sleep(200);
READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");

} catch (InterruptedException | DeadLockException e) {
StackTraceElement[] ee = e.getStackTrace();
System.out.println(Thread.currentThread().getName() +"抛出异常");
for (StackTraceElement stackTraceElement : ee) {
System.out.println(stackTraceElement.toString());
}

} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
}

}
}
public static class UnDeadReadWrite implements Runnable{

@Override
public void run() {
try {


READ_WRITE_LOCK.writeLock();
System.out.println(Thread.currentThread().getName() + "获取到了写锁");
Thread.sleep(200);
READ_WRITE_LOCK.readLock();
System.out.println(Thread.currentThread().getName() + "获取到了读锁");


} catch (InterruptedException | DeadLockException e) {
System.out.println(Thread.currentThread().getName() + e.getLocalizedMessage());
} finally {
System.out.println(Thread.currentThread().getName() + "准备放弃读锁");
READ_WRITE_LOCK.readUnlock();
System.out.println(Thread.currentThread().getName() + "准备放弃写锁");
READ_WRITE_LOCK.writeUnLock();

}

}
}

public static class DeadLockException extends Exception{


}
}
分享到:
评论

相关推荐

    操作系统实验--读写锁

    3. **锁升级与降级**:在某些高级实现中,读写锁支持锁升级和降级的概念。如果一个线程先持有了读锁,然后发现自己需要进行写操作,它可以升级为写锁。写操作完成后,如果可能,该线程可以降级回读锁,而不必立即...

    读写锁源代码(C#编写)

    3. **升级与降级**:C#的读写锁还支持锁的升级和降级。这意味着一个线程可以在持有读锁的情况下升级为写锁(写升级),并在完成写操作后降级回读锁(写降级)。这是一个高级特性,但需要谨慎使用,因为错误的操作...

    java 门锁终于被打开了(解决死锁)

    6. **死锁检测与恢复**:Java的`java.lang.management.LockInfo`和`java.lang.management.ThreadInfo`类可以用来检测和分析死锁。通过JMX接口,可以监控应用中的死锁情况。 7. **使用Condition**:`ReentrantLock`...

    WINDOWS读写锁实现

    在Windows操作系统中,读写锁(Read-Write Lock)是一种多线程同步原语,它允许多个线程同时读取共享资源,但在写入时仅允许一个线程访问。这提高了并发性能,尤其是在读操作远多于写操作的场景下。本篇文章将深入...

    Java多线程程序死锁检查 JCarder

    5. 分析和解决:根据报告,开发者可以定位到具体引起死锁的代码,然后调整锁的顺序、增加超时机制或者使用更高级的同步机制(如读写锁、信号量)来避免死锁。 除了JCarder,Java还提供了其他的死锁检测工具和手段,...

    windows和linux读写锁C++实现

    在C++中,还可以使用智能指针(如`std::unique_lock`或`std::shared_lock`)与读写锁配合,以实现RAII(Resource Acquisition Is Initialization)风格的代码,这样可以更安全地管理锁的生命周期。 总的来说,...

    java死锁源码java死锁源码

    java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁源码java死锁...

    linux下实现高性能读写锁(read/write lock)

    3. **升级与降级**:在某些高级实现中,线程可能需要从读锁升级到写锁,或者从写锁降级回读锁。这需要特别小心处理,以防止死锁和数据不一致性。 在Linux内核中,`&lt;pthread_rwlock_t&gt;`结构代表了一个读写锁,提供了...

    windows 读写锁 (基于关键区的读写锁类 及自动锁)

    其中,读写锁(Read-Write Lock,简称RWLock)是一种高效的线程同步机制,适用于大量读取操作和少量写入操作的情况。在本文中,我们将深入探讨基于关键区的Windows读写锁类及其自动锁的实现原理和改进点。 读写锁的...

    java 一个死锁的例子

    为了识别死锁,可以使用Java的`jstack`命令查看线程堆栈信息,寻找处于"WAITING"或"TIMED_WAITING"状态并且持有锁的线程,如果发现它们都在等待其他线程释放资源,那么可能就存在死锁。 避免死锁的方法有多种,比如...

    linux写优先的读写锁设计

    linux写优先的读写锁设计 在 Linux 操作系统中,有两种基本机制来实现数据互斥,即信号量(semaphore)和自旋锁(spinlock)。本文将讨论一种特殊的自旋锁变种,即读写锁(read-write lock),它允许多个进程同时...

    彻底理解Java中的各种锁.pdf

    本文将详细介绍Java中包括乐观锁、悲观锁、自旋锁、可重入锁、读写锁等多种锁机制的概念、特点、应用场景及其优化技术。 1. 乐观锁与悲观锁 乐观锁与悲观锁反映了对数据并发访问策略的不同预期。乐观锁假设数据通常...

    java模拟线程死锁

    Java 模拟线程死锁 线程死锁 在 Java 中,线程死锁(Deadlock)是一种特殊的情况,发生在两个或多个线程之间的互相等待对方释放资源的状态。这种情况下,各个线程都在等待其他线程释放资源,而自己也占用着其他...

    java多线程-读写锁原理

    这样即使在try块中有异常抛出,也能确保锁最终会被释放,防止资源被不当占用。 读写锁的实现中,如上述示例所示,通过`wait()`和`notifyAll()`方法管理线程的等待与唤醒。读锁的获取允许在没有写锁请求和写锁持有时...

    解决sqlite死锁示例异常database is locked示例

    "database is locked"错误是SQLite在遇到死锁情况时抛出的异常,意味着数据库当前处于锁定状态,无法进行预期的操作。本文将深入探讨SQLite死锁的原因、诊断方法以及解决策略。 **1. SQLite死锁原因** SQLite死锁...

    android jni抛出异常

    当我们尝试在JNI代码中抛出一个异常时,实际上是在JNI层创建了一个本地异常,这个异常会在下一次JNI方法返回到Java层时被抛出。 在标题“android jni抛出异常”中,我们关注的是如何在JNI层生成并传递异常到Java层...

    Windows下读写锁的实现

    在实现读写锁时,需要注意异常处理,确保在发生异常时能正确地释放锁,避免死锁的发生。 5. **代码实现:** 使用C++标准库中的`std::mutex`和`std::condition_variable`可以简化Windows下的读写锁实现。不过,...

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    本文将深入探讨标题和描述中提及的各种锁,包括乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁以及行级锁。 1. **乐观锁**:乐观锁假设多线程环境中的冲突较少,所以在读取数据时不加锁,只有...

    读写锁_读写锁_

    读写锁是多线程编程中的一个重要概念,用于提高并发访问数据时的效率。在并发环境中,如果多个线程同时读取数据,...通过深入理解读写锁的工作原理,并在实际项目中谨慎应用,我们可以构建出更加高效、可靠的并发程序。

Global site tag (gtag.js) - Google Analytics