
正文
简单java死锁代码 java 死锁代码
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
java synchronized 死锁问题
synchronized(obj){ ... } 称之为对obj加锁简单java死锁代码的同步代码块。 你可以这么理解,每一个java对象,都具有一个锁标记。而这个锁标记,同时只能分配给一个线程。 有synchronized(o),意思是只有获得o对象的锁标记之后,后面的代码块才会执行,否则会等待。 回到你的例子。x1和x2是两个不同的Xianc对象,但是,对于static的属性来说,任何Xianc对象都共享相同的值。因此,实际上,x1的o1属性和x2的o1属性指向同一个对象,而x1的o2属性和x2的o2属性也指向相同的对象。 也就是说,Xianc.o1和Xianc.o2表示两个对象,这两个对象被x1和x2作为静态属性共享。 然后,简单java死锁代码我们开始考虑锁标记的事情。程序中创建简单java死锁代码了两个线程t1和t2,并首先启动了t1线程。t1线程与x1绑定,此时执行的是flag == 0的代码块。 首先,遇到sync(o2),由于此时o2的锁标记还没有被分配,因此t1线程就能获得o2的锁标记,进入代码块。 进入代码块之后,接下来是sleep。由于t1线程sleep之后,释放了cpu,导致t2线程开始运行。由于t2线程与x2绑定,此时执行的是flag == 1的代码块。 这时,t2线程遇到sync(o1)。由于o1的锁标记没有被分配,因此t2线程就能获得o1的锁标记,进入代码块。同样的,进入代码块之后,t2也进入了sleep状态,释放了CPU。 过了一段时间,t1率先苏醒,并被执行。但是执行过程中,会遇到syn(o1)。此时,o1的锁标记被t2线程占据,t1无法获得锁标记,于是t1只能等待。 在等待过程中,t2也苏醒了。但是t2遇到了syn(o2),而此时o2的锁标记被t1占据,因此t2也只能等待。 于是,两个线程相互等待,就形成了死锁。 手打,楼主给分
相关问答
Q1: java执行cmd命令时出现死锁
line = bufferedReader.readLine();//死锁位置
会等待,所以会。
用另一个线程读、主线程检测是否命令终止了。
Q2: java怎么编程写一个能导致死锁的程序
额,这么简单,就直接定义一个类,该类随便定义实例化个Object对象,然后在类中再定义2个内部线程类,线程一,对object使用synchronized,在synchronized块中用个while(true)的死循环就好了,线程二,对object也是使用synchronized同步,至于synchronized块中干啥,你自己看着办,反正线程一死循环不会释放object对象锁,线程二是执行不到里面的代码块的
Q3: 北大青鸟java培训:在Java程序中处理数据库超时与死锁?
每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避免死锁等问题,文章以DB2(版本9)与为例进行讲解。
什么是数据库锁定与死锁锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性;在设计与数据库交互的程序时,必须处理锁与资源不可用的情况。
锁定是个比较复杂的概念,仔细说起来可能又需要一大篇,所以在本文中,只把锁定看作是一个临时事件,这意味着如果一个资源被锁定,它总会在以后某个时间被释放。
而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。
如何避免锁我们可利用事务型数据库中的隔离级别机制来避免锁的创建,正确地使用隔离级别可使程序处理更多的并发事件(如允许多个用户访问数据),还能预防像丢失修改(LostUpdate)、读“脏”数据(DirtyRead)、不可重复读(NonrepeatableRead)及“虚”(Phantom)等问题。
隔离级别问题现象丢失修改读“脏”数据不可重复读“虚”可重复读取NoNoNoNo读取稳定性NoNoNoYes光标稳定性NoNoYesYes未提交的读NoYesYesYes表1:DB2的隔离级别与其对应的问题现象在只读模式中,就可以防止锁定发生,而不用那些未提交只读隔离级别的含糊语句。
山西电脑培训发现一条SQL语句当使用了下列命令之一时,就应该考虑只读模式了
Q4: dump 怎么分析死锁
1、首先构造死锁简单java死锁代码,代码如下:
public class Deadlocker {
private static Object lock_1 = new int[1];
private static Object lock_2 = new int[1];
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("thread 1 start");
synchronized (lock_1) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread 1 get lock 1 need lock 2");
synchronized (lock_2) {
}
}
System.out.println("thread 1 end");
}
}
public class Thread2 extends Thread {
@Override
public void run() {
System.out.println("thread 2 start");
synchronized (lock_2) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread 2 get lock 2 need lock 1");
synchronized (lock_1) {
}
}
System.out.println("thread 2 end");
}
}
public static void main(String[] args) {
Thread1 thread1 = new Deadlocker().new Thread1();
Thread2 thread2 = new Deadlocker().new Thread2();
thread1.start();
thread2.start();
}
}
2、运行结果如下:
thread 1 start
thread 2 start
thread 1 get lock 1 need lock 2
thread 2 get lock 2 need lock 1
3、分析:
从打印的结果很容易分析线程1 和线程2 处于死锁。相互需要对方的持有的锁;
4、使用:jps 查看线程id简单java死锁代码,再使用:jstack 线程id dumpthread 命令。部分结果如下(去除各种gc线程。。。):
第一部分:
"Thread-1" prio=10 tid=0x0000000040a49800 nid=0x2d1e waiting for monitor entry [0x00007f50eda98000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlocker$Thread2.run(Deadlocker.java:47)
- waiting to lock 0x00000007d6f97ec8 (a [I)
- locked 0x00000007d6f97ee0 (a [I)
"Thread-0" prio=10 tid=0x0000000040a47800 nid=0x2d1d waiting for monitor entry [0x00007f50edb99000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlocker$Thread1.run(Deadlocker.java:28)
- waiting to lock 0x00000007d6f97ee0 (a [I)
- locked 0x00000007d6f97ec8 (a [I)
。。。。。各种其简单java死锁代码他线程
这里可以看出两个线程处于BLOCKED 状态,各自在等待各自的锁( 0x00000007d6f97ec8 和0x00000007d6f97ee0 )
第二部分:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000000040a33dd8 (object 0x00000007d6f97ec8, a [I),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000040a365e0 (object 0x00000007d6f97ee0, a [I),
which is held by "Thread-1"
这个一看就更明白简单java死锁代码了。。说发现一个java死锁,Thread-1在等待一个lock,而这个锁被Thread-0 持有,
而 Thread-0在等待另外一个lock,而这个锁被Thread-1 持有
Java stack information for the threads listed above:
===================================================
"Thread-1":
at Deadlocker$Thread2.run(Deadlocker.java:47)
- waiting to lock 0x00000007d6f97ec8 (a [I)
- locked 0x00000007d6f97ee0 (a [I)
"Thread-0":
at Deadlocker$Thread1.run(Deadlocker.java:28)
- waiting to lock 0x00000007d6f97ee0 (a [I)
- locked 0x00000007d6f97ec8 (a [I)
Found 1 deadlock.
上面的红色部分便也可以清楚查询到死锁的位置了;
当然据说第二部分只有java5 以上版本才有的(未验证)。
Q5: java 死锁
死锁
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。
由于这个原因,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作的情形。代码一是一个导致死锁的简单例子。
//代码一
class Deadlocker {
int field_1;
private Object lock_1 = new int[1];
int field_2;
private Object lock_2 = new int[1];
public void method1(int value) {
“synchronized” (lock_1) {
“synchronized” (lock_2) {
field_1 = 0; field_2 = 0;
}
}
}
public void method2(int value) {
“synchronized” (lock_2) {
“synchronized” (lock_1) {
field_1 = 0; field_2 = 0;
}
}
}
}
参考代码一,考虑下面的过程:
◆ 一个线程(ThreadA)调用method1()。
◆ ThreadA在lock_1上同步,但允许被抢先执行。
◆ 另一个线程(ThreadB)开始执行。
◆ ThreadB调用method2()。
◆ ThreadB获得lock_2,继续执行,企图获得lock_1。但ThreadB不能获得lock_1,因为ThreadA占有lock_1。
◆ 现在,ThreadB阻塞,因为它在等待ThreadA释放lock_1。
◆ 现在轮到ThreadA继续执行。ThreadA试图获得lock_2,但不能成功,因为lock_2已经被ThreadB占有简单java死锁代码了。
◆ ThreadA和ThreadB都被阻塞,程序死锁。
当然,大多数的死锁不会这么显而易见,需要仔细分析代码才能看出,对于规模较大的多线程程序来说尤其如此。好的线程分析工具,例如JProbe Threadalyzer能够分析死锁并指出产生问题的代码位置。
隐性死锁
隐性死锁由于不规范的编程方式引起,但不一定每次测试运行时都会出现程序死锁的情形。由于这个原因,一些隐性死锁可能要到应用正式发布之后才会被发现,因此它的危害性比普通死锁更大。下面介绍两种导致隐性死锁的情况:加锁次序和占有并等待。
加锁次序
当多个并发的线程分别试图同时占有两个锁时,会出现加锁次序冲突的情形。如果一个线程占有了另一个线程必需的锁,就有可能出现死锁。考虑下面的情形,ThreadA和ThreadB两个线程分别需要同时拥有lock_1、lock_2两个锁,加锁过程可能如下:
◆ ThreadA获得lock_1简单java死锁代码;
◆ ThreadA被抢占,VM调度程序转到ThreadB;
◆ ThreadB获得lock_2;
◆ ThreadB被抢占,VM调度程序转到ThreadA;
◆ ThreadA试图获得lock_2,但lock_2被ThreadB占有,所以ThreadA阻塞;
◆ 调度程序转到ThreadB;
◆ ThreadB试图获得lock_1,但lock_1被ThreadA占有,所以ThreadB阻塞;
◆ ThreadA和ThreadB死锁。
必须指出的是,在代码丝毫不做变动的情况下,有些时候上述死锁过程不会出现,VM调度程序可能让其中一个线程同时获得lock_1和lock_2两个锁,即线程获取两个锁的过程没有被中断。在这种情形下,常规的死锁检测很难确定错误所在。
占有并等待
如果一个线程获得了一个锁之后还要等待来自另一个线程的通知,可能出现另一种隐性死锁,考虑代码二。
//代码二
public class queue {
static java.lang.Object queueLock_;
Producer producer_;
Consumer consumer_;
public class Producer {
void produce() {
while (!done) {
“synchronized” (queueLock_) {
produceItemAndAddItToQueue();
“synchronized” (consumer_) {
consumer_.notify();
}
}
}
}
public class Consumer {
consume() {
while (!done) {
“synchronized” (queueLock_) {
“synchronized” (consumer_) {
consumer_.wait();
}
removeItemFromQueueAndProcessIt();
}
}
}
}
}
}
在代码二中,Producer向队列加入一项新的内容后通知Consumer,以便它处理新的内容。问题在于,Consumer可能保持加在队列上的锁,阻止Producer访问队列,甚至在Consumer等待Producer的通知时也会继续保持锁。这样,由于Producer不能向队列添加新的内容,而Consumer却在等待Producer加入新内容的通知,结果就导致了死锁。
在等待时占有的锁是一种隐性的死锁,这是因为事情可能按照比较理想的情况发展—Producer线程不需要被Consumer占据的锁。尽管如此,除非有绝对可靠的理由肯定Producer线程永远不需要该锁,否则这种编程方式仍是不安全的。有时“占有并等待”还可能引发一连串的线程等待,例如,线程A占有线程B需要的锁并等待,而线程B又占有线程C需要的锁并等待等。
要改正代码二的错误,只需修改Consumer类,把wait()移出“synchronized”()即可。
简单java死锁代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java 死锁代码、简单java死锁代码的信息别忘了在本站进行查找喔。





