public class Test {
Object leftLock = new Object();
Object rightLock = new Object();
public static void main(String[] args) {
final Test test = new Test();
Thread a = new Thread(new Runnable() {
@Override public void run() {
int i=0;
while (i<10)
{
test.leftRight();
i++;
}
}
},"aThread");
Thread b = new Thread(new Runnable() {
@Override public void run() {
int i=0;
while (i<10)
{
test.rightleft();
i++;
}
}
},"bThread");
a.start();
b.start();
}
public void leftRight(){
synchronized (leftLock){
System.out.println(Thread.currentThread().getName()+":leftRight:get left");
synchronized (rightLock){
System.out.println(Thread.currentThread().getName()+":leftRight:get right");
}
}
}
public void rightleft(){
synchronized (rightLock){
System.out.println(Thread.currentThread().getName()+":rightleft: get right");
synchronized (leftLock){
System.out.println(Thread.currentThread().getName()+":rightleft: get left");
}
}
}
}
复制代码
运行后输出以下java
aThread:leftRight:get left
bThread:rightleft: get right
复制代码
能够经过jstack发现死锁的痕迹bash
"bThread" prio=5 tid=0x00007fabb2001000 nid=0x5503 waiting for monitor entry [0x000000011d54b000]
java.lang.Thread.State: BLOCKED (on object monitor)
at main.lockTest.Test.rightleft(Test.java:52)
- waiting to lock <0x00000007aaee5748> (a java.lang.Object)
- locked <0x00000007aaee5758> (a java.lang.Object)
at main.lockTest.Test$2.run(Test.java:30)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"aThread" prio=5 tid=0x00007fabb2801000 nid=0x5303 waiting for monitor entry [0x000000011d448000]
java.lang.Thread.State: BLOCKED (on object monitor)
at main.lockTest.Test.leftRight(Test.java:43)
- waiting to lock <0x00000007aaee5758> (a java.lang.Object)
- locked <0x00000007aaee5748> (a java.lang.Object)
at main.lockTest.Test$1.run(Test.java:19)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
复制代码
能够看到bThread
持有锁0x00000007aaee5758
,同时等待0x00000007aaee5748
,然而刚好aThread
持有锁0x00000007aaee5748
并等待0x00000007aaee5758
,从而造成了死锁app
public class ExecutorLock {
private static ExecutorService single=Executors.newSingleThreadExecutor();
public static class AnotherCallable implements Callable<String>{
@Override public String call() throws Exception {
System.out.println("in AnotherCallable");
return "annother success";
}
}
public static class MyCallable implements Callable<String>{
@Override public String call() throws Exception {
System.out.println("in MyCallable");
Future<String> submit = single.submit(new AnotherCallable());
return "success:"+submit.get();
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable task = new MyCallable();
Future<String> submit = single.submit(task);
System.out.println(submit.get());
System.out.println("over");
single.shutdown();
}
}
复制代码
执行的输出只有一行ide
in MyCallable
复制代码
经过jstack观察能够看到以下ui
"main" prio=5 tid=0x00007fab3f000000 nid=0x1303 waiting on condition [0x0000000107d63000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007aaeed1d8> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:425)
at java.util.concurrent.FutureTask.get(FutureTask.java:187)
at main.lockTest.ExecutorLock.main(ExecutorLock.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Locked ownable synchronizers:
- None
..
"pool-1-thread-1" prio=5 tid=0x00007fab3f835800 nid=0x5303 waiting on condition [0x00000001199ee000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007ab0f8698> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:425)
at java.util.concurrent.FutureTask.get(FutureTask.java:187)
at main.lockTest.ExecutorLock$MyCallable.call(ExecutorLock.java:26)
at main.lockTest.ExecutorLock$MyCallable.call(ExecutorLock.java:20)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x00000007aaeed258> (a java.util.concurrent.ThreadPoolExecutor$Worker)
复制代码
主线程在等待一个FutureTask完成,而线程池中一个线程也在等待一个FutureTask完成。
从代码实现能够看到,主线程往线程池中扔了一个任务A,任务A又往同一个线程池中扔了一个任务B,并等待B的完成,因为线程池中只有一个线程,这将致使B会被停留在阻塞队列中,而A还得等待B的完成,这也就是互相等待致使了死锁的反生spa
这种因为正在执行的任务线程都在等待其它工做队列中的任务而阻塞的现象称为 线程饥饿死锁线程
并未产生线程阻塞,可是因为某种问题的存在,致使没法继续执行的状况。code
消息重试。当某个消息处理失败的时候,一直重试,但重试因为某种缘由,好比消息格式不对,致使解析失败,而它又被重试队列
这种时候通常是将不可修复的错误不要重试,或者是重试次数限定资源
相互协做的线程彼此响应从而修改本身状态,致使没法执行下去。好比两个颇有礼貌的人在同一条路上相遇,彼此给对方让路,可是又在同一条路上遇到了。互相之间反复的避让下去
这种时候能够选择一个随机退让,使得具有必定的随机性