死锁问题:

  例如有两个线程, 线程1与线程2.

  线程1在执行的过程中, 要锁定对象1, 2才能完成整个操作, 首先锁定对象1, 再锁定对象2.

  线程2在执行的过程中, 要锁定对象2, 1才能完成整个操作, 首先锁定对象2, 再锁定对象1.

  某时刻, 线程1已经拥有对象1的锁, 要是再拥有对象2的锁就能完成整个操作, 可惜了, 你等待着的对象2的锁已经被别人拥有了, 执行不下去了.

  此时刻, 线程2已经拥有对象2的锁, 要是再拥有对象1的锁就能完成整个操作, 可惜了, 你等待着的对象1的锁已经被别人拥有了, 执行不下去了.

  两个对象都已经锁了, 腰都要求对象放锁, 不可能, 那就都等着吧............

死锁例程:

public class DeadLock implements Runnable{
public int flag ;
static Object o1 = new Object();
static Object o2 = new Object();
@Override
public void run() {
System.out.println("flag: "+flag);
if(flag == 1) {
synchronized(o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized(o2){
System.out.println("1");
}
}
if(flag == 0){
synchronized(o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized(o1){
System.out.println("0");
}
}
}
public static void main(String[] args) {
DeadLock de1 = new DeadLock();
DeadLock de2 = new DeadLock();
de1.flag = 1;
de2.flag = 0;
Thread t1 = new Thread(de1);
Thread t2 = new Thread(de2);
t1.start();
t2.start();
}
}

Demo_1:

public class TT1 implements Runnable {
public int b;
public synchronized void m1() throws Exception { // 只是方法锁定而已, 别的线程无法执行它
b = 1000; // 其他的线程无法再调用它(方法里面的东西(语句))
Thread.sleep(5000);
System.out.println("b = "+b);
}
public void m2() {
System.out.println(b);
}
@Override
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
TT1 tt1 = new TT1();
Thread t = new Thread(tt1);
t.start();
Thread.sleep(1000);
tt1.m2();
}
}

运行结果:

1000
b = 1000

Demo_2:

public class TT2 implements Runnable {
public int b = 100;
public synchronized void m1() throws Exception { // 互斥, 在某一时刻, 保证只有一个线程进入我们这个方法里面
b = 1000; // 但是, 不保证其他的线程是不是能够进入到另外一个方法里面
Thread.sleep(5000);
System.out.println("b = "+b);
}
public void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}
@Override
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
TT2 tt = new TT2();
Thread t = new Thread(tt);
t.start();
tt.m2();
}
}

运行结果:

b = 2000

  在Demo_2中, 如果在 m2() 的方法也加 synchronized. 同时在主方法中的 tt.m2() 后面加一句: System.out.println(tt.b);

则, 运行结果为:

1000

b = 1000 // 这句话执行得比较快.

【注】:当某个对象调用了同步方法时, 该对象上的其它同步方法必须等待该同步方法执行完毕后, 才能被执行.

【注】:其实, 写一个同步的东西是挺困难的. 因为每一个方法要不要同步, 你要考虑得非常清楚.如果一个方法

    做了同步, 另外一个方法没有做同步, 那么你要记住一点: 别的线程可以自由得访问那个非同步的方法,

    并且可能会对你那个同步的方法产生影响, 所以你要保护好某一个类里面的某一个对象的话, 或者说你

    要保护好需要同步的那个对象的话, 你必须对访问这个对象的所有方法仔细考虑, 加不加同步, 加了同

    步, 很有可能效率很低, 不加同步, 有可能产生数据不一致的现象.

Java中的死锁问题的更多相关文章

  1. java中的死锁现象

    死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. java 死锁产生的四个必要条件: 1.互斥使用,即当资源被一个线 ...

  2. 死锁线程探讨Java中的死锁现象

    题记:写这篇博客要主是加深自己对死锁线程的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 今天搞了一下Java的死锁机制,感到自己还是不怎么懂,所以就从一些简略的源代码中琢磨:我先 ...

  3. 编写 Java 程序时, 如何在 Java 中创建死锁并修复它?

    经典但核心Java面试问题之一.如果你没有参与过多线程并发 Java 应用程序的编码,你可能会失败.

  4. Java多线程中的死锁问题

    Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...

  5. java中多线程产生死锁的原因以及解决意见

    1.  java中导致死锁的原因 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结 ...

  6. 5000字 | 24张图带你彻底理解Java中的21种锁

    本篇主要内容如下: 本篇文章已收纳到我的Java在线文档. Github 我的SpringCloud实战项目持续更新中 帮你总结好的锁: 序号 锁名称 应用 1 乐观锁 CAS 2 悲观锁 synch ...

  7. Java中的主线程

    目录 概览 主线程 怎么来控制主线程 主线程和main()函数的关系 主线程中的死锁(单个线程) 概览 前段时间有同事提到了主线程这个名词,但当时我们说的主线程是指Java Web程序中每一个请求进来 ...

  8. JAVA中关于同步与死锁的问题

    java中当多个现成同时操纵同一资源的时候需要考虑同步的问题.如车站售票,不同售票点卖同一班次车票的时候就要同步,否则卖票会有问题.下面代码模拟车站卖票: class TicketSeller imp ...

  9. Java多线程中的死锁

    Java多线程中的死锁 死锁产生的原因 线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行. 当线程进入对象的synchronized代码块时,便占有了资源,直到 ...

随机推荐

  1. mint-ui message box 问题;

    当引用 mint-ui message box 的 出现的问题,我暂时是不知道为什么: 官网是这样写的: 于是 我也这么做的:(这里用小写,具体我也不清楚,毕竟文档上写的也不是很清楚,但是只有这样写, ...

  2. JavaScript深入之参数按值传递

    在<JavaScript高级程序设计>第三版 4.1.3,讲到传递参数: ECMAscript中所有函数的参数都是按值传递 按值传递 也就是,把函数外部的值复制给函数内部的参数,就和把值从 ...

  3. 虚拟机下linux 系统网卡配置、固定IP地址

    1.进入该目录下修改内容 vi       /etc/sysconfig/network-scripts/  ifcfg-eth0 TYPE=Ethernet BOOTPROTO=static DEF ...

  4. PHP批量清理MIP-cache缓存(内附在线mipcache清理工具)

    MIP是什么?我就不多说了把. MIPCache 又是什么? 科普一下:MIPCache 是一套基于代理的 CDN 缓存系统.可用于缓存所有被某度相关页面引用或者从百度相关服务点出的 MIP 页面.当 ...

  5. 关于php中数字0与其他变量的相等判断

    在实践过程中,经常需要做`==`判断,有时候会把0当做false一样用,但是0和false在用来做比较的时候还是不一样的, false false==0 等于true false=='0' 等于tru ...

  6. Leecode刷题之旅-C语言/python-141环形链表

    /* * @lc app=leetcode.cn id=141 lang=c * * [141] 环形链表 * * https://leetcode-cn.com/problems/linked-li ...

  7. Hangfire初探

    Hangfire 是什么? Hangfire 是一个定时任务的管理后台,它拥有定时任务功能和及其相关的管理后台界面.Hangfire 原生使用 .NET 开发的,同时支持 .NET 和 .NET Co ...

  8. 成都Uber优步司机奖励政策(3月12日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  9. ORB-SLAM(五)KeyFrame类-最小生成树

    KeyFrame中维护了一个map,保存了与当前帧共视的KeyFrame*与权重(共视MapPonits数量).对关键帧之间关系是用加权有向图来完成的,那么理解其spanning tree生成树的原理 ...

  10. 跨平台编译Go程序(交叉编译)

    作用:比如你手头只有Mac系统,而你的用户有Linux和Windows的,他们也想用,你可以通过交叉编译出Linux和Windows上的可执行文件给他们用 (1)首先进入go/src 源码所在目录,执 ...