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("读结束");
}
}
分享到:
相关推荐
### Java多线程-避免同步机制带来的死锁问题及用Lock锁解决线程安全问题 #### 死锁 ##### 1.... 在多线程编程中,死锁是一种...同时,合理利用 `Lock` 接口提供的功能可以帮助开发者更加灵活地管理线程间的同步问题。
6. **原子操作(Atomic Operation)**:这是在多线程环境中执行不会被中断的操作,例如自增或自减,以确保数据一致性。 然而,多线程通信也存在潜在的危险。其中最常见的问题是**竞态条件(Race Condition)**,即多个...
- **中断线程**:通过调用`interrupt()`方法可以请求线程停止执行,但实际停止需要线程内部配合检查`isInterrupted()`或捕获`InterruptedException`。 - **死锁**:当两个或更多线程相互等待对方释放资源而造成的一...
- interrupt()方法用于中断线程,如果线程正在阻塞(如sleep或wait),会被中断并抛出InterruptedException。 通过这些技术,我们可以构建高效、稳定、响应迅速的多线程应用程序。在实际开发中,应根据具体需求...
6. **异常处理**:多线程环境下的异常处理需要特别注意,因为一个线程的异常可能会中断其他线程。大漠的模板可能包含了优雅的异常处理机制,确保线程异常不会导致整个程序崩溃。 7. **线程间通信**:`WaitHandle`类...
Java的Thread类提供了start()来启动线程,interrupt()来中断线程,但需要注意的是,中断并不一定能立即停止线程,线程需要自行检查并响应中断状态。 另外,可能还会涉及到死锁、活锁和饥饿等并发问题,这些都是多...
3. **线程同步控制**:利用synchronized、wait()、notify()和notifyAll()进行线程间的通信和同步,以及使用Lock和Condition来实现更复杂的同步策略。 实验内容涵盖了三个典型的多线程场景: 1. **象棋大师与多个...
- interrupt():中断线程,被中断的线程会抛出InterruptedException。 - isInterrupted() 和 interrupted():检查线程是否被中断。 三、线程同步 为了解决多线程并发访问共享资源可能导致的问题,Java提供了多种...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提升系统效率和资源利用率。本文将深入探讨Java多线程机制,包括线程的创建、同步、通信以及常见设计模式。 首先,Java中创建线程主要有两种...
- **线程中断**:线程可以在指定的中断点被中断,这对于需要在特定时刻停止线程执行的场景非常有用。 - **通用条件变量**:条件变量现在可以与任何实现了`Lockable`概念的类型配合使用,增强了其适用范围。 - **线程...
在IT行业中,线程是操作系统分配CPU执行时间的...通过上述知识点,"线程的各种使用方式Demo"可能涵盖了线程的创建、管理、同步、通信等多个方面,有助于开发者深入理解线程的使用,并在实际项目中高效地利用多线程。
为此,Java提供了`synchronized`关键字、`wait()`, `notify()`和`notifyAll()`方法,以及`Lock`接口和相关的类(如`ReentrantLock`)来实现线程同步,避免竞态条件。 4. **死锁**:当两个或更多线程互相等待对方...
6. 线程中断:通过interrupt()方法可以中断线程,但需要注意中断并不立即停止线程,而是设置一个中断标志,线程需要检查这个标志并适当地响应。 7. 线程局部变量(ThreadLocal):每个线程都有自己的副本,确保了...
- 线程控制:包括join()(等待线程执行完毕)、interrupt()(中断线程)和yield()(让出CPU执行权)等方法。 4. **线程同步与通信**: - 竞态条件:当多个线程访问和修改同一数据时,可能会出现不一致的结果。...
此外,`Lock`接口还支持更复杂的并发控制策略,如可中断的锁等待(`tryLock()`方法),以及通过`Condition`对象实现线程间的条件等待和精确唤醒。 在实际应用中,`ReentrantLock`是`Lock`接口最常见的实现,它具有...
在Java编程领域,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高系统资源的利用率和程序的响应速度。这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点...
在单线程环境中,程序按照顺序执行任务,而在多线程环境中,程序可以同时执行多个独立的任务,这有助于充分利用处理器资源,提升用户体验。VB中实现多线程通常依赖于`System.Threading`命名空间中的类,如`Thread`和...
在C#中,可以使用锁(Mutex, Monitor, Semaphore等)、线程同步块(lock关键字)、线程间通信(WaitHandle类)等方式来控制线程的执行顺序和访问共享资源,避免数据不一致和死锁等问题。 在实际开发中,合理利用...
线程组可以包含线程和其他线程组,可以设置权限,也可以进行统一的中断或中止操作。 总之,Java线程是并发编程的基础,理解和掌握线程的生命周期、实现方式和同步机制对于编写高效、安全的多线程程序至关重要。在...