ReentrantLock 的lock机制有2种,忽略中断锁和响应中断锁,这给我们带来了很大的灵活性。比如:如果A、B2个线程去竞争锁,A线程得到了锁,B线程等待,但是A线程这个时候实在有太多事情要处理,就是一直不返回,B线程可能就会等不及了,想中断自己,不再等待这个锁了,转而处理其他事情。这个时候ReentrantLock 就提供了2种机制,第一,B线程中断自己(或者别的线程中断它),但是ReentrantLock 不去响应,继续让B线程等待,你再怎么中断,我全当耳边风(synchronized原语就是如此);第二,B线程中断自己(或者别的线程中断它),ReentrantLock 处理了这个中断,并且不再等待这个锁的到来,完全放弃。请看例子:
import java.util.concurrent.locks.ReentrantLock;
public class TestLock
{
// 是用ReentrantLock,还是用synchronized
public static boolean useSynchronized = false;
public static void main(String[] args)
{
IBuffer buff = null;
if (useSynchronized)
{
buff = new Buffer();
}
else
{
buff = new BufferInterruptibly();
}
final Writer writer = new Writer(buff);
final Reader reader = new Reader(buff);
writer.start();
reader.start();
new Thread(new Runnable()
{
public void run()
{
long start = System.currentTimeMillis();
for (;;)
{
// 等5秒钟去中断读
if (System.currentTimeMillis() - start > 5000)
{
System.out.println("不等了,尝试中断");
reader.interrupt();
break;
}
}
}
}).start();
}
}
interface IBuffer
{
public void write();
public void read() throws InterruptedException;
}
class Buffer implements IBuffer
{
private Object lock;
public Buffer()
{
lock = this;
}
public void write()
{
synchronized (lock)
{
long startTime = System.currentTimeMillis();
System.out.println("开始往这个buff写入数据…");
for (;;)// 模拟要处理很长时间
{
if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
break;
}
System.out.println("终于写完了");
}
}
public void read()
{
synchronized (lock)
{
System.out.println("从这个buff读数据");
}
}
}
class BufferInterruptibly implements IBuffer
{
private ReentrantLock lock = new ReentrantLock();
public void write()
{
lock.lock();
try
{
long startTime = System.currentTimeMillis();
System.out.println("开始往这个buff写入数据…");
for (;;)// 模拟要处理很长时间
{
if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
break;
}
System.out.println("终于写完了");
}
finally
{
lock.unlock();
}
}
public void read() throws InterruptedException
{
lock.lockInterruptibly();// 注意这里,可以响应中断
try
{
System.out.println("从这个buff读数据");
}
finally
{
lock.unlock();
}
}
}
class Writer extends Thread
{
private IBuffer buff;
public Writer(IBuffer buff)
{
this.buff = buff;
}
@Override
public void run()
{
buff.write();
}
}
class Reader extends Thread
{
private IBuffer buff;
public Reader(IBuffer buff)
{
this.buff = buff;
}
@Override
public void run()
{
try
{
buff.read();
}
catch (InterruptedException e)
{
System.out.println("我不读了");
}
System.out.println("读结束");
}
}
分享到:
相关推荐
互斥体Mutex和事件对象EventWaitHandler属于内核对象,利用内核对象进行线程同步,线程必须要在用户模式和内核模 式间切换,所以一般效率很低,但利用互斥对象和事件对象这样的内核对象,可以在多个进程中的各个...
为了避免数据不一致和竞争条件,项目使用了Java的同步机制(如synchronized关键字、Lock接口等)来确保线程安全。 3. 断点续传:项目基于Http协议实现了断点续传功能。当下载过程中出现异常或网络中断时,可以从...
书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高...
常规的内置锁是无法中断一个正在等待获取锁的线程,以及无法在请求获取一个锁的无限等待下去。 ReentrantLock标准使用方式 Lock lock=new ReentrantLock(); lock.lock(); try{ //具体任务 }finally{ ...
高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4 高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4 高并发编程第三阶段06讲 AtomicLong源码分析.mp4 高并发编程第三阶段07...
高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4 高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4 高并发编程第三阶段06讲 AtomicLong源码分析.mp4 高并发编程第三阶段07...
17.3.1 Lock接口与ReentrantLock类简介 386 17.3.2 ReentrantLock锁的具体使用 387 17.3.3 ReadWriteLock接口与ReentrantReadWriteLock类简介 390 17.3.4 ReentrantReadWriteLock读/写锁的具体使用 391 17.4...
1,跳过不是OD设的Int 3中断,跳过STATUS_GUARD_PAGE,STATUS_INVALID_LOCK_SEQUENCE异常 2,正确处理int 2d指令 [2008.08.31 v0.16] 1,加入驱动,保护进程,隐藏窗口,过绝大部分反调试 2,驱动支持自定义设备名...
# 这个值(默认8)表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中, # 如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,...
其中包括文件、文件映射、进程、线程、安全和同步对象等 CompareFileTime 对比两个文件的时间 CopyFile 复制文件 CreateDirectory 创建一个新目录 CreateFile 打开和创建文件、管道、邮槽、通信服务、设备以及...
主要是介绍各种格式流行的软件设计模式,对于程序员的进一步提升起推进作用,有时间可以随便翻翻~~ 23种设计模式汇集 如果你还不了解设计模式是什么的话? 那就先看设计模式引言 ! 学习 GoF 设计模式的重要性 ...