各种同步工具使用

1. 如何使用 ReentrantLock 中的 可中断锁防止死锁?

答: 在 执行语句前 加 可中断锁,此时,当被打断时,会抛出 被中断异常,这样就可以解锁。

注意:要外部中断,死锁中的线程不会自己中断

public class ReentrantLockTest {
    static Lock lock1 = new ReentrantLock();
    static Lock lock2 = new ReentrantLock();
    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(new ThreadDemo(lock1, lock2));//该线程先获取锁1,再获取锁2
        Thread thread1 = new Thread(new ThreadDemo(lock2, lock1));//该线程先获取锁2,再获取锁1
        thread.start();
        thread1.start();
        thread.interrupt();//是第一个线程中断,这个地方也可以弄一个线程 专门检查死锁,然后中断其中一个线程
    }

    static class ThreadDemo implements Runnable {
        Lock firstLock;
        Lock secondLock;
        public ThreadDemo(Lock firstLock, Lock secondLock) {
            this.firstLock = firstLock;
            this.secondLock = secondLock;
        }
        @Override
        public void run() {
            try {
                firstLock.lockInterruptibly();
                TimeUnit.MILLISECONDS.sleep(10);//更好的触发死锁
                secondLock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                firstLock.unlock();
                secondLock.unlock();
                System.out.println(Thread.currentThread().getName()+"正常结束!");
            }
        }
    }
}

2.   ReentrantLock还给我们提供了获取锁限时等待的方法tryLock(),可以选择传入时间参数,表示等待指定的时间,无参则表示立即返回锁申请的结果:true表示获取锁成功,false表示获取锁失败。我们可以使用该方法配合失败重试机制来更好的解决死锁问题。

例子:

package com.xuecheng.manage_cms;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 同步控制工具 ReentrantLock
 */
public class ReentrantLockTest implements Runnable{
    private  ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            if(lock.tryLock(5, TimeUnit.SECONDS)){
                Thread.sleep(6000);
            }else{
                System.out.println("get lock fail");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
            System.out.println("lock unlocked");
        }
    }

    public static void main(String[] args) {
        ReentrantLockTest task = new ReentrantLockTest();
        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);
        thread1.start();
        thread2.start();
    }
}

执行结果为:

get lock fail
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.xuecheng.manage_cms.ReentrantLockTest.run(ReentrantLockTest.java:24)
    at java.lang.Thread.run(Thread.java:745)
lock unlocked

抛出异常原因为: 获取锁失败的线程 并没有持有监视器的锁,却释放了监视器的锁

原文地址:https://www.cnblogs.com/yk414/p/12019353.html

时间: 2024-08-29 09:10:59

各种同步工具使用的相关文章

【java并发】线程同步工具CyclicBarrier的使用

上一节中总结了Semaphore同步工具的使用,Semaphore主要提供了一个记数信号量,允许最大线程数运行.CyclicBarrier是另一个同步工具,这一节主要来总结一下CyclicBarrier的使用.先看一下官方的对CyclicBarrier的介绍: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用.因为该 barrier

Linux的rsync远程数据同步工具

Rsync(remote synchronize) 是一个远程数据同步工具,可以使用"Rsync算法"同步本地和远程主机之间的文件. rsync的好处是只同步两个文件不同的部分,相同的部分不在传递.类似于增量备份, 这使的在服务器传递备份文件或者同步文件,比起scp工具要省好多时间. OS:ubuntu server 10.04 server:192.168.64.128 client:192.168.64.145 server 1.ubuntu  server 10.04默认已安装r

12306订票助手文件版本同步工具

using System; using System.Collections.Generic; using System.Text; using System.Linq; namespace TicketPackageSyncTool { class Program { /// <summary> /// 当前的根路径 /// </summary> static string _root; static string _chromePath; static string _outp

深入分析同步工具类之CountDownLatch

概览: CountDownLatch又称闭锁,其作用是让一个或者多个线程挂起,直到其他的线程执行完后恢复挂起的线程,使其继续执行.内部维护着一个静态内部类Sync,该类继承AbstractQueuedSynchronizer(这个类之前分析过了,参见    深入分析同步工具类之AbstractQueuedSynchronizer),Sync实例维护着state属性,调用await()方法,使当前线程挂起,当一个线程执行完后,调用countDown()方法,state-1,直到state变为0,被

线程:Exchanger同步工具

可以在对中对元素进行配对和交换的线程的同步点,类似于交易,A拿着钱到达指定地点,B拿着物品到达指定地点,相互交换,然后各自忙各自的事去了. 1 package ch03; 2 3 import java.util.concurrent.Exchanger; 4 5 public class ExchangerTest { 6 7 public static void main(String[] args) { 8 final Exchanger<String> changer = new Ex

线程:CountDownLatch同步工具

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 类似计数器,当计数器的值为0时,继续往下执行. 1 package ch03; 2 3 import java.util.Random; 4 import java.util.concurrent.CountDownLatch; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 8

文件夹自动同步工具

这是我之前开发的文件夹自动同步工具,主要实现开发机和服务器之间的文件夹同步. 项目地址: https://github.com/mike-zhang/autoSync 问题描述 在windows下修改代码,到服务器上去编译,但每次都要通过winscp之类的工具拖拽上去(当然你也可以通过scp命令行的方式). 每次修改的文件很少,而且可能位于不同的目录,每次都重复覆盖文件的操作感觉比较麻烦,所以开发了这个自动文件夹自动同步工具. 当然这个工具也可以用于两台linux服务器之间的文件夹同步. 工具介

Rsync数据同步工具应用指南

1.Rsync数据同步工具应用指南 简介Rsync的特性:Rsync的工作方式:Rsync命令同步选项参数:本地主机模式示例远程RPC模式示例 简介     Rsync是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具.可使本地和远程两台或多台主机之间的数据快速复制同步镜像.远程备份的功能.这个功能类似ssh自带的scp命令,但又优于scp命令的功能,scp每次都是全量拷贝,而rsync可以增量拷贝.当然,Rsync还可以在本地主机的不同分区或目录之间全量及增量的

《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&amp;并发容器类&amp;同步工具类,消费者模式

上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Hashtable,此外还包括在JDK1.2中添加的一些功能相似的类,这些同步的封装器类由Collections.synchronizedXxx等工厂方法创建的.这些类实现线程安全的方式是:将他们的状态封装起来,并对每个共有方法都进行同步,使得每次只能有一个线程能访问容器的状态. 关于java中的Vect

rsync同步工具实战

rsync同步工具实战 rsync具有增量同步的功能,相对于cp工具来说,效率比较高:同时可以在本地到本地或本地到远程之间,实现镜像备份 环境:分别有机器:server-178/24,client-b-179/24,client-c-180/24 其中以server-178/24为rsync服务端,client-b-179/24,client-c-180/24为rsync客户端 实战过程: 检查服务端和客户端环境:rpm -aq|grep rsync [[email protected] ~]#