java 常见线程阻塞及解决方案

/**

* @author liangjun

* @descriptionTODO

* alphonse gaston 两个对象相互等着对方释放锁,线程阻塞,造成死锁

*/

public
class
Friend {

private
final
String name;

public Friend(String name) {

this.name = name;

}

public String getName() {

return
this
.name;

}

public
synchronized void
bow(Friend bower){

System.out.format("%s: %s"

+ "  has bowed to me!%n",

this.name, bower.getName());

bower.bowBack(this);

}

public
synchronized void
bowBack(Friendbower) {

System.out.format("%s: %s"

+ " has bowed back to me!%n",

this.name, bower.getName());

}

public
static void
main(String[] args) {

final Friend alphonse =

new Friend("Alphonse");

final Friend gaston =

new Friend("Gaston");

new Thread(new Runnable() {

public
void
run() { alphonse.bow(gaston); }

}).start();

new Thread(new Runnable() {

public
void
run() { gaston.bow(alphonse); }

}).start();

}

}

/**

* @author liangjun

* @descriptionTODO

* 1.同一对象多线程分别调用method1 method2时,

* 2.ThreadA获得锁lock_1,ThreadB获得lock_2,

* 3.ThreadA继续执行获得lock_2时,或者ThreadB继续执行获得lock_1时,lock_2/lock_1分别被对方占有,

* 4.ThreadA/ThreadB线程阻塞,造成死锁现象

*

*/

class Deadlocker {

int
field_1;

private Objectlock_1 =
newint[1];

int
field_2;

private Objectlock_2 =
newint[1];

public
void
method1(int value) {

synchronized (lock_1) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("当前线程:" + Thread.currentThread().getName());

synchronized (lock_2) {

field_1 = 0;

field_2 = 0;

System.out.println("method1");

}

}

}

public
void
method2(int value) {

synchronized (lock_2) {

System.out.println("当前线程:" + Thread.currentThread().getName());

synchronized (lock_1) {

field_1 = 0;

field_2 = 0;

System.out.println("method2");

}

}

}

public
static void
main(String args[]) {

final Deadlocker dl =new Deadlocker();

new Thread(new Runnable() {

@Override

public
void
run() {

dl.method1(0);

}

}).start();

new Thread(new Runnable() {

@Override

public
void
run() {

dl.method2(1);

}

}).start();

}

}

/**

* 解决方案:让所有的线程按照同样的顺序获得一组锁

*       将多个锁组成一组并放到同一个锁下

*/

时间: 2024-11-12 08:19:48

java 常见线程阻塞及解决方案的相关文章

Java多线程——线程阻塞工具类LockSupport

简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执行的情况. 和 Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出 InterruptedException 异常. LockSupport 的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos().parkUntil()等方法.它们实现了一个限时等待,如下图

Android学习:UI线程阻塞post解决方案

一:看程序 二:post方法 //线程阻塞优化方案1:post方法 v.post(new Runnable() { @Override public void run() { int sum = 10; TextView view = (TextView) v; view.setText("" + sum); } }); 三:后台日志 说明post方法,执行内容放到UI主线程执行.

JAVA并发实现四(守护线程和线程阻塞)

守护线程     Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通.非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程.当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护者,也就没有继续运行程序的必要了.如果有非守护线程仍然存活,VM就不会退出. 守护线程并非只有虚拟机内部提

多线程之Java线程阻塞与唤醒

线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题.如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节.在Java发展史上曾经使用suspend().resume()方法对于线程进行阻塞唤醒,但随之出现很多问题,比较典型的还是死锁问题.如下代码,主要的逻辑代码是主线程启动线程mt一段时间后尝试使用suspend()让线程挂起,最后使用resume()恢复线程.但现实并不如愿,执行到suspend()时将一直卡住

Java线程阻塞中断和LockSupport的常见问题

上周五和周末,工作忙里偷闲,在看java cocurrent中也顺便再温故了一下Thread.interrupt和java 5之后的LockSupport的实现. 在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? Thread.interrupt()会中断线程什么状态的工作? RUNNING or BLOCKING? 一般Thread编程需要关注

【Java并发编程】之四:守护线程与线程阻塞的四种情况

守护线程   Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通.非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程.当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护这,也就没有继续运行程序的必要了.如果有非守护线程仍然存活,VM就不会退出. 守护线程并非只有虚拟机内部提供,

转:【Java并发编程】之四:守护线程与线程阻塞的四种情况

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981      守护线程   Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通.非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程.当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,

跟我学Java多线程——线程池与阻塞队列

前言 上一篇文章中我们将ThreadPoolExecutor进行了深入的学习和介绍,实际上我们在项目中应用的时候很少有直接应用ThreadPoolExecutor来创建线程池的,在jdk的api中有这么一句话"但是,强烈建议程序员使用较为方便的 Executors 工厂方法Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收).Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleT

【Java并发编程】:守护线程与线程阻塞的四种情况

守护线程 JAVA中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通.非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程.当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护这,也就没有继续运行程序的必要了.如果有非守护线程仍然存活,VM就不会退出. 守护线程并非只有虚拟机内部提供,用户