jdk线程的死锁

两个线程相互等着对方释放同步监听器;等着要对方的结果后才能继续执行就会发生死锁。

男对女说:你先嫁给我,我再给你买房子;女对男说:你先给我买房子,我再嫁给你。

多个线程同时锁住同一个监听对象

在开发中要避免死锁。

死锁的例子:

public class DeadLock {
    public static void main(String[] args) {
        Resource r1 = new Resource();
        Resource r2 = new Resource();

        // 每个线程都拥有r1,r2两个对象
        Thread myTh1 = new MyThread1(r1, r2);
        Thread myTh2 = new MyThread2(r1, r2);

        myTh1.start();
        myTh2.start();
    }
}

class Resource {
    private int i;
}

class MyThread1 extends Thread {
    private Resource r1, r2;

    public MyThread1(Resource r1, Resource r2) {
        this.r1 = r1;
        this.r2 = r2;
    }

    @Override
    public void run() {
        while (true) {
            // 先获得r1的锁,再获得r2的锁
            synchronized (r1) {
                System.out.println("1号线程获取了r1的锁");
                synchronized (r2) {
                    System.out.println("1号线程获取了r2的锁");
                }
            }
        }
    }
}

class MyThread2 extends Thread {
    private Resource r1, r2;

    public MyThread2(Resource r1, Resource r2) {
        this.r1 = r1;
        this.r2 = r2;
    }

    @Override
    public void run() {
        while (true) {
            // 先获得r2的锁,再获得r1的锁
            synchronized (r2) {
                System.out.println("2号线程获取了r2的锁");
                synchronized (r1) {
                    System.out.println("2号线程获取了r1的锁");
                }
            }
        }
    }
}
时间: 2024-11-13 11:07:48

jdk线程的死锁的相关文章

jdk线程池主要原理

本文转自:http://blog.csdn.net/linchengzhi/article/details/7567397 正常创建一个线程的时候,我们是这样的:new thread(Runnable实现类).这里,thread是线程,Runnable实现类是业务逻辑,这样线程和业务逻辑紧紧绑定在一起. 采用线程池来处理的时候,我们动态生成若干个线程存于池中,但是这些线程要执行那些业务逻辑是不知道的,由于业务逻辑个数和具体的逻辑需要用户来指定,这些是变化的,我们需要自己编写并存于linkedLi

java并发-线程饥饿死锁测试

线程饥饿死锁 <Java并发编程实践>中对线程饥饿死锁的解释是这样的:在使用线程池执行任务时,如果任务依赖于其他任务,那么就可能产生死锁问题.在单线程的Executor中,若果一个任务将另一个任务提交到同一个Executor,并且等待这个被提交的任务的结果,那么这必定会导致死锁.第一个任务在工作队列中,并等待第二个任务的结果:而第二个任务则处于等待队列中,等待第一个任务执行完成后被执行.这就是典型的线程饥饿死锁.即使是在多线程的Executor中,如果提交到Executor中的任务之间相互依赖

JDK线程池原理剖析

这篇文章不打算讲解什么是线程池?线程池怎么用?直接讲解原理 1.线程池关键参数解释 JDK 线程池的实现类是 ThreadPoolExecutor,构造函数关键参数解释如下: corePoolSize 核心线程,线程池维持的线程数量,即使没有任务执行也会维持这个数量不变,除非设置了 allowCoreThreadTimeOut 这个参数为 true maximumPoolSize 线程池中允许创建线程的最大数量 keepAliveTime 非核心线程的空闲等待时间,超过这个时间将被销毁 unit

如何检查线程是否死锁了?

产生死锁的四个必要条件 (1) 互斥条件:一个资源每次只能被一个进程(线程)使用.(2) 请求与保持条件:一个进程(线程)因请求资源而阻塞时,对已获得的资源保持不放.(3) 不剥夺条件 : 此进程(线程)已获得的资源,在末使用完之前,不能强行剥夺.(4) 循环等待条件 : 多个进程(线程)之间形成一种头尾相接的循环等待资源关系. 可以使用 jstack或者pstack 和 gdb 工具对死锁程序进行分析. pstack: 功能是打印输出此进程的堆栈信息.可以输出所有线程的调用关系栈 jstack

线程的死锁

今天本人给大家讲解一下多线程的死锁,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 线程死锁 什么是线程的死锁? 产生死锁的原因? 因为资源的竞争:线程中都是进行抢占CPU的时间片的执行权,所以开启多线程可以一次性进行多个功能的使用,可是现在因为锁对象A和锁对象B的执行时机以及顺序的的不一致,导致线程相互等待,有时候会出现死锁的现象. 预防死锁 保证我们请求的资源数据的顺序要一致即可 案例:出现死锁的案例 public class Demo01 { p

查看jdk 线程 日志

命令:jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 这些命令 必须 在 linux jdk bin 路径 下执行 eq: ./jstack 10303 即可  如果想把 内容打印到 文本里 即 ./jstack 10303 >111.log  打印 到 111.log文件 中,然后 sz  111.log 下载到本地查看. jmap -histo pid(查看实例) 怎么知道当前linux系统下的jdk路径,可以ps aux|grep jdk 可以看出路径,一般为/

jdk线程的简单使用

一.线程的实现方式方式一:继承Thread类一个类只要继承了Thread类,并重写run()方法,则就可以实现多线程的操作. public class ThreadDemo01 { public static void main(String[] args) { Thread1 thread1 = new Thread1("thread1"); Thread2 thread2 = new Thread2("thread2"); System.out.println(

谈谈JDK线程的伪唤醒

在JDK的官方的wait()方法的注释中明确表示线程可能被“虚假唤醒“,JDK也明确推荐使用while来判断状态信息.那么这种情况的发生的可能性有多大呢? 使用生产者消费者模型来说明,伪唤醒造成的后果是本来未被唤醒的线程被唤醒了,那么就破坏了生产者消费者中的判断条件,也就是例子中的while条件number == 0或者number == 1.最终导致的结果就死0和1不能交替出现. JDK的两种同步方案均可能出现这种伪唤醒的问题(API说明明确表示会出现这种现象),这两种组合是synchroni

JDK线程池的使用

转载自:https://my.oschina.net/hosee/blog/614319: 摘要: 本系列基于炼数成金课程,为了更好的学习,做了系列的记录. 本文主要介绍: 1. 线程池的基本使用 2. 扩展和增强线程池 3. ForkJoin 1. 线程池的基本使用 1.1.为什么需要线程池 平时的业务中,如果要使用多线程,那么我们会在业务开始前创建线程,业务结束后,销毁线程.但是对于业务来说,线程的创建和销毁是与业务本身无关的,只关心线程所执行的任务.因此希望把尽可能多的cpu用在执行任务上