java线程死锁例子及解决方法
2017-12-03 11:20
369 查看
Java线程死锁是由于有些资源彼此交叉取用,就有可能造成死结.
[java] view
plain copy
如1线程中 取得A对象的锁定后又要取得B对象的锁定.但是同时2线程中取得B对象的锁定后又要取得A对象的锁定.这两个线程同时发生时就会造成,1线程拿到A对象锁定后等待B对象的锁定.2线程拿到B对象锁定后等待A对象锁定.这样就会进入没有停止的等待中.
[java] view
plain copy
线程死锁的一个简单例子:
[java] view
plain copy
package deadLockThread;
public class Test {
private int size=0;
public synchronized void doSome(){
size++;
}
public synchronized void doTest(Test test){
try {
Thread.sleep(1000);//睡眠1秒 效果更明显
} catch (InterruptedException e) {
e.printStackTrace();
}
test.doSome(); //另外一个对象调用synchronized 函数 需要取得该对象的对象锁定
}
}
[java] view
plain copy
package deadLockThread;
public class DeadLock {
public static void main(String[] args) {
final Test t1=new Test();
final Test t2=new Test();
Thread th1=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t1.doTest(t2);
}
});
Thread th2=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t2.doTest(t1);
}
});
th1.start();
th2.start();
}
}
[java] view
plain copy
如果真的没办法避免资源的交叉取用 我的解决方法是使用并行API在取得第一个对象锁定前先检测另外一个对象的对象锁定有没有被其他的线程拿走了.
[java] view
plain copy
synchronized 要求线程必须取得对象锁定,才可以执行所标识的区块范围.然而使用synchronized 有许多的限制,未取得锁定的线程会直接被打断.所以我这里使用并行API Lock 替代直接操作synchronized .
[java] view
plain copy
package deadLockThread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
private int size = 0;
private Lock lock = new ReentrantLock();
public void doSome() {
System.out.println(Thread.currentThread().getName() + "获取size");
size++;
}
public void doTest(Test test) {
while (true) {
boolean myLock = this.lock.tryLock();// 尝试取得当前对象的Lock锁定
boolean testLock = test.lock.tryLock();// 尝试取得被传入得对象的Lock锁定
try {
if (myLock && testLock) { //当两个对象的Lock 都获取到后再进行 操作
test.doSome();
break;
}
} finally {
if (myLock) {
this.lock.unlock();
}
if (testLock) {
test.lock.unlock();
}
}
}
}
}
[java] view
plain copy
package deadLockThread;
public class DeadLock {
public static void main(String[] args) {
final Test t1 = new Test();
final Test t2 = new Test();
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t1.doTest(t2);
}
});
Thread th2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t2.doTest(t1);
}
});
th1.start();
th2.start();
}
}
[java] view
plain copy
如1线程中 取得A对象的锁定后又要取得B对象的锁定.但是同时2线程中取得B对象的锁定后又要取得A对象的锁定.这两个线程同时发生时就会造成,1线程拿到A对象锁定后等待B对象的锁定.2线程拿到B对象锁定后等待A对象锁定.这样就会进入没有停止的等待中.
[java] view
plain copy
线程死锁的一个简单例子:
[java] view
plain copy
package deadLockThread;
public class Test {
private int size=0;
public synchronized void doSome(){
size++;
}
public synchronized void doTest(Test test){
try {
Thread.sleep(1000);//睡眠1秒 效果更明显
} catch (InterruptedException e) {
e.printStackTrace();
}
test.doSome(); //另外一个对象调用synchronized 函数 需要取得该对象的对象锁定
}
}
[java] view
plain copy
package deadLockThread;
public class DeadLock {
public static void main(String[] args) {
final Test t1=new Test();
final Test t2=new Test();
Thread th1=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t1.doTest(t2);
}
});
Thread th2=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t2.doTest(t1);
}
});
th1.start();
th2.start();
}
}
[java] view
plain copy
如果真的没办法避免资源的交叉取用 我的解决方法是使用并行API在取得第一个对象锁定前先检测另外一个对象的对象锁定有没有被其他的线程拿走了.
[java] view
plain copy
synchronized 要求线程必须取得对象锁定,才可以执行所标识的区块范围.然而使用synchronized 有许多的限制,未取得锁定的线程会直接被打断.所以我这里使用并行API Lock 替代直接操作synchronized .
[java] view
plain copy
package deadLockThread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
private int size = 0;
private Lock lock = new ReentrantLock();
public void doSome() {
System.out.println(Thread.currentThread().getName() + "获取size");
size++;
}
public void doTest(Test test) {
while (true) {
boolean myLock = this.lock.tryLock();// 尝试取得当前对象的Lock锁定
boolean testLock = test.lock.tryLock();// 尝试取得被传入得对象的Lock锁定
try {
if (myLock && testLock) { //当两个对象的Lock 都获取到后再进行 操作
test.doSome();
break;
}
} finally {
if (myLock) {
this.lock.unlock();
}
if (testLock) {
test.lock.unlock();
}
}
}
}
}
[java] view
plain copy
package deadLockThread;
public class DeadLock {
public static void main(String[] args) {
final Test t1 = new Test();
final Test t2 = new Test();
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t1.doTest(t2);
}
});
Thread th2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
t2.doTest(t1);
}
});
th1.start();
th2.start();
}
}
相关文章推荐
- java线程死锁例子及解决方法
- JAVA多线程-生产者与消费者当线程多时发生死锁的解决方法
- 一个Java线程死锁的例子
- Java并发编程:死锁及解决方法
- 4个小例子看java线程挂起方法
- java 线程死锁的小例子
- Java线程死锁需要如何解决
- Java线程同步卖票问题解决方法
- Java-java线程:两个实现方法,死锁现象,线程通讯,线程停止等
- java解决线程不安全问题的方法
- Java 解决死锁的方法实例详解
- 引起线程死锁的一种情况及解决方法
- Java线程死锁的简单例子
- Java线程(学习整理)--3--简单的死锁例子
- 深入学习理解java:高效的解决死锁问题的线程通讯方式:Semaphore 和 BlockingQueue
- 黑马程序员--JAVA基础复习之多线程(二)线程安全与解决方法
- Java 线程死锁的问题解决办法
- java中的线程死锁的一个例子
- ajax 同步调用 返回字符串 java例子(全)及 从后台返回中文乱码解决方法
- Java SimpleDateFormat 线程不安全问题及解决方法