博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA并发| 记录一次死锁(二)与Locked ownable synchronizers
阅读量:4182 次
发布时间:2019-05-26

本文共 8858 字,大约阅读时间需要 29 分钟。

package com.xiaobu.deadlock;import java.util.concurrent.*;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/8/21 17:16 * @description */public class ExcuteLock {
static ExecutorService single = Executors.newSingleThreadExecutor(); static class AnotherCallable implements Callable
{
@Override public String call() throws Exception {
System.out.println(" in AnotherCallable"); return "success another"; } } static class MyCallable implements Callable
{
@Override public String call() throws Exception {
System.out.println("in MyCallable"); Future
future = single.submit(new AnotherCallable()); return "success "+future.get(); } } /** * 功能描述:主线程在等待一个FutureTask完成,而线程池中一个线程也在等待一个FutureTask完成。 * 从代码实现可以看到,主线程往线程池中扔了一个任务A,任务A又往同一个线程池中扔了一个任务B,并等待B的完成,由于线程池中只有一个线程,这将导致B会被停留在阻塞队列中,而A还得等待B的完成,这也就是互相等待导致了死锁的反生 * @author xiaobu * @date 2019/8/22 16:14 * @return void * @version 1.0 */ public static void main(String[] args) {
MyCallable myCallable = new MyCallable(); Future
submit = single.submit(myCallable); try {
System.out.println(submit.get()); } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); } System.out.println("over"); }}

1566475159(1)

RMI:(Remote Method Invocation)一种用于实现远程过程调用的应用程序编程接口。

JMX:(Java Management Extensions,即Java管理扩展)是Java平台上为应用程序、设备、系统等植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。

Locked ownable synchronizers: 一个可持有的同步器多半是线程独有并且使用了AbstractOwnableSynchronizer(或是其子类)去实现它的同步特性,ReentrantLock与ReentrantReadWriteLock就是JAVA平台提供的两个例子。

可以看出第一个Locked ownable synchronizers下面有对应的锁的信息,因为ThreadPoolExecutor.Worker 继承了AbstractQueuedSynchronizer,AbstractQueuedSynchronizer继承了AbstractOwnableSynchronizer

结构图

第二个的话没有使用AbstractOwnableSynchronizer或其子类。所以没有锁定同步器.

package com.xiaobu.learn.deadlock;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/6/26 14:53 * @description  synchronized内置锁线程池调用,而线程池里面用到的ThreadPoolExecutor.Worker 继承了AbstractQueuedSynchronizer */public class Demo1 {
public static void main(String[] args) {
final Object a = new Object(); final Object b = new Object(); //ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build(); ThreadFactory threadFactory2 = new ThreadFactory() {
@Override public Thread newThread(Runnable r) {
return new Thread(r); } }; ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), threadFactory2); executor.execute(() -> {
try {
synchronized (a) {
System.out.println(Thread.currentThread().getName() + " got the lock of a"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " was trying to get the lock of b"); synchronized (b) {
System.out.println(Thread.currentThread().getName() + " win"); } } } catch (InterruptedException e) {
e.printStackTrace(); } }); executor.execute(() -> {
try {
synchronized (b) {
System.out.println(Thread.currentThread().getName() + " got the lock of b"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " was trying to get the lock of a"); synchronized (a) {
System.out.println(Thread.currentThread().getName() + " win"); } } } catch (InterruptedException e) {
e.printStackTrace(); } }); }}

demo1.jpg

package com.xiaobu.learn.deadlock;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/6/26 14:53 * @description synchronized内置锁 new Thread 显示调用 */public class Demo2 {
public static void main(String[] args) {
final Object a = new Object(); final Object b = new Object(); //ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build(); ThreadFactory threadFactory2 = new ThreadFactory() {
@Override public Thread newThread(Runnable r) {
return new Thread(r); } }; ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), threadFactory2); new Thread(new Runnable() {
@Override public void run() {
try {
synchronized (a) {
System.out.println(Thread.currentThread().getName() + " got the lock of a"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " was trying to get the lock of b"); synchronized (b) {
System.out.println(Thread.currentThread().getName() + " win"); } } } catch (InterruptedException e) {
e.printStackTrace(); } } }).start(); new Thread(new Runnable() {
@Override public void run() {
try {
synchronized (b) {
System.out.println(Thread.currentThread().getName() + " got the lock of b"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " was trying to get the lock of a"); synchronized (a) {
System.out.println(Thread.currentThread().getName() + " win"); } } } catch (InterruptedException e) {
e.printStackTrace(); } } }).start(); }}

demo2.jpg

package com.xiaobu.learn.deadlock;import java.util.concurrent.locks.ReentrantLock;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/9/23 15:44 * @description ReentrantLock实现锁 */public class Demo3 {
static class AThread extends Thread {
private ReentrantLock lock1; private ReentrantLock lock2; public AThread(ReentrantLock lock1, ReentrantLock lock2) {
super(); this.lock1 = lock1; this.lock2 = lock2; } public void run() {
try {
lock1.lock(); Thread.sleep(3000); // 必须获取两个锁后才执行操作 lock2.lock(); System.out.println("A: I have all Locks!"); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
lock2.unlock(); lock1.unlock(); } } } static class BThread extends Thread {
private ReentrantLock lock1; private ReentrantLock lock2; public BThread(ReentrantLock lock1, ReentrantLock lock2) {
super(); this.lock1 = lock1; this.lock2 = lock2; } public void run() {
try {
lock2.lock(); Thread.sleep(1000); // 必须获取两个锁后才执行操作 lock1.lock(); System.out.println("B: I have all Locks!"); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
lock1.unlock(); lock2.unlock(); } } } // 测试程序主函数 public static void main(String[] args) throws InterruptedException {
final ReentrantLock lock1 = new ReentrantLock(); final ReentrantLock lock2 = new ReentrantLock(); new AThread(lock1, lock2).start(); new BThread(lock1, lock2).start(); }}

demo3.jpg

发现ReentrantLock与内置锁有如下3点不同:

  1. 等待的对象不同,内置锁是“monitor entry”(监视器进入点),而ReentrantLock是“condition”(条件)。
  2. 线程的状态不同,内置锁是“BLOCKED”,而ReentrantLock是“WAITING”。
  3. 锁定的同步器不同,内置锁没有,而ReentrantLock则指向持有的同步器。

2

活锁:相互协作的线程彼此响应从而修改自己状态,导致无法执行下去。比如两个很有礼貌的人在同一条路上相遇,彼此给对方让路,但是又在同一条路上遇到了。互相之间反复的避让下去。

参考:

转载地址:http://sgrai.baihongyu.com/

你可能感兴趣的文章
Ubuntu18.04查看显卡信息并安装NVDIA显卡驱动driver + Cuda + Cudnn
查看>>
电子元件二极管封装SMA,SMB,SMC的区别
查看>>
利用FFmpeg玩转Android视频录制与压缩(二)
查看>>
eclipse下生成Java类图和时序图,生成UML图
查看>>
M文件程序设计(matlab)
查看>>
matlab基础知识
查看>>
程序员的职业素养
查看>>
一道面试题深入了解java底层
查看>>
java下载附件
查看>>
cron表达式每个月最后一天
查看>>
Oracle中Like与Instr模糊查询性能大比拼
查看>>
Spring Boot入门===Hello World
查看>>
spring boot应用启动原理分析
查看>>
使用spring的好处
查看>>
微服务:分解应用以实现可部署性和可扩展性
查看>>
log4j2 使用详解
查看>>
spring security
查看>>
java线程池管理多线程的应用
查看>>
redis集群图解
查看>>
tcp_timestamps tcp_tw_recycle引起的服务器连接不上问题
查看>>