`
coach
  • 浏览: 386700 次
  • 性别: Icon_minigender_2
  • 来自: 印度
社区版块
存档分类
最新评论

利用lock中断线程

阅读更多
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锁解决线程安全问题

    ### Java多线程-避免同步机制带来的死锁问题及用Lock锁解决线程安全问题 #### 死锁 ##### 1.... 在多线程编程中,死锁是一种...同时,合理利用 `Lock` 接口提供的功能可以帮助开发者更加灵活地管理线程间的同步问题。

    多线程之间的线程通信

    6. **原子操作(Atomic Operation)**:这是在多线程环境中执行不会被中断的操作,例如自增或自减,以确保数据一致性。 然而,多线程通信也存在潜在的危险。其中最常见的问题是**竞态条件(Race Condition)**,即多个...

    创建线程类轻松实现线程管理

    - **中断线程**:通过调用`interrupt()`方法可以请求线程停止执行,但实际停止需要线程内部配合检查`isInterrupted()`或捕获`InterruptedException`。 - **死锁**:当两个或更多线程相互等待对方释放资源而造成的一...

    java多线程Demo

    - interrupt()方法用于中断线程,如果线程正在阻塞(如sleep或wait),会被中断并抛出InterruptedException。 通过这些技术,我们可以构建高效、稳定、响应迅速的多线程应用程序。在实际开发中,应根据具体需求...

    大漠多线程模板_大漠_大漠多线程_

    6. **异常处理**:多线程环境下的异常处理需要特别注意,因为一个线程的异常可能会中断其他线程。大漠的模板可能包含了优雅的异常处理机制,确保线程异常不会导致整个程序崩溃。 7. **线程间通信**:`WaitHandle`类...

    java 多线程并发实例

    Java的Thread类提供了start()来启动线程,interrupt()来中断线程,但需要注意的是,中断并不一定能立即停止线程,线程需要自行检查并响应中断状态。 另外,可能还会涉及到死锁、活锁和饥饿等并发问题,这些都是多...

    多线程实验

    3. **线程同步控制**:利用synchronized、wait()、notify()和notifyAll()进行线程间的通信和同步,以及使用Lock和Condition来实现更复杂的同步策略。 实验内容涵盖了三个典型的多线程场景: 1. **象棋大师与多个...

    java线程实例 各种小Demo

    - interrupt():中断线程,被中断的线程会抛出InterruptedException。 - isInterrupted() 和 interrupted():检查线程是否被中断。 三、线程同步 为了解决多线程并发访问共享资源可能导致的问题,Java提供了多种...

    java多线程详解(比较详细的阐述了多线程机制)

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提升系统效率和资源利用率。本文将深入探讨Java多线程机制,包括线程的创建、同步、通信以及常见设计模式。 首先,Java中创建线程主要有两种...

    boost线程指南手册

    - **线程中断**:线程可以在指定的中断点被中断,这对于需要在特定时刻停止线程执行的场景非常有用。 - **通用条件变量**:条件变量现在可以与任何实现了`Lockable`概念的类型配合使用,增强了其适用范围。 - **线程...

    线程的各种使用方式Demo

    在IT行业中,线程是操作系统分配CPU执行时间的...通过上述知识点,"线程的各种使用方式Demo"可能涵盖了线程的创建、管理、同步、通信等多个方面,有助于开发者深入理解线程的使用,并在实际项目中高效地利用多线程。

    多线程thread线程的理解

    为此,Java提供了`synchronized`关键字、`wait()`, `notify()`和`notifyAll()`方法,以及`Lock`接口和相关的类(如`ReentrantLock`)来实现线程同步,避免竞态条件。 4. **死锁**:当两个或更多线程互相等待对方...

    【JAVA多线程】多线程编程核心技术学习资料

    6. 线程中断:通过interrupt()方法可以中断线程,但需要注意中断并不立即停止线程,而是设置一个中断标志,线程需要检查这个标志并适当地响应。 7. 线程局部变量(ThreadLocal):每个线程都有自己的副本,确保了...

    pb多线程实现的例程

    - 线程控制:包括join()(等待线程执行完毕)、interrupt()(中断线程)和yield()(让出CPU执行权)等方法。 4. **线程同步与通信**: - 竞态条件:当多个线程访问和修改同一数据时,可能会出现不一致的结果。...

    第四节(Lock关键字用法)

    此外,`Lock`接口还支持更复杂的并发控制策略,如可中断的锁等待(`tryLock()`方法),以及通过`Condition`对象实现线程间的条件等待和精确唤醒。 在实际应用中,`ReentrantLock`是`Lock`接口最常见的实现,它具有...

    JAVA多线程编程技术PDF

    在Java编程领域,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高系统资源的利用率和程序的响应速度。这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点...

    VB 多线程 多个参数传入

    在单线程环境中,程序按照顺序执行任务,而在多线程环境中,程序可以同时执行多个独立的任务,这有助于充分利用处理器资源,提升用户体验。VB中实现多线程通常依赖于`System.Threading`命名空间中的类,如`Thread`和...

    线程后台的作用演示

    在C#中,可以使用锁(Mutex, Monitor, Semaphore等)、线程同步块(lock关键字)、线程间通信(WaitHandle类)等方式来控制线程的执行顺序和访问共享资源,避免数据不一致和死锁等问题。 在实际开发中,合理利用...

    Java线程详解大全

    线程组可以包含线程和其他线程组,可以设置权限,也可以进行统一的中断或中止操作。 总之,Java线程是并发编程的基础,理解和掌握线程的生命周期、实现方式和同步机制对于编写高效、安全的多线程程序至关重要。在...

Global site tag (gtag.js) - Google Analytics