一,synchronized的用法:
详见:
synchronized的用法_Morning sunshine的博客-CSDN博客
二,线程执行任务:
2.1,任务描述:
有两个对象资源LockA和LockB,
有一个任务task1,先获取LockA,利用LockA去执行一些业务逻辑,再获取LockB,利用LockB去执行一些业务逻辑。
线程A去执行任务task1。
2.1,代码示例:
有两个对象资源LockA和LockB:
public class LockA {
}
public class LockB {
}
有一个任务task1,先获取LockA,利用LockA去执行一些业务逻辑,再获取LockB,利用LockB去执行一些业务逻辑。
private static LockA lockA = new LockA();
private static LockB lockB = new LockB();
/**
* 任务1:
* 任务1中的任务是:1,首先拿到锁资源A,然后利用锁资源A去做一些事情...
*/
public static void task01() {
System.out.println(Thread.currentThread().getName() + "正在执行任务1...");
System.out.println("任务1——1,首先拿到锁资源A...");
synchronized (lockA) {
System.out.println("任务1——已拿到拿到锁资源A" + lockA.toString() + ",然后利用锁资源A去做一些事情...");
System.out.println("任务1——2,再去获取锁资源B...");
synchronized (lockB) {
System.out.println("任务1——已拿到拿到锁资源B" + lockB.toString() + ",然后利用锁资源B去做一些事情...");
System.out.println("任务1——结束...");
}
}
}
线程A去执行任务task1。
public static void main(String[] args) {
//创建线程A:
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 线程进入运行状态...,执行任务1...");
try {
task01();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "线程A");
//启动两个线程的start()方法,使其进入就绪状态:
threadA.start();
}
打印结果:
线程A 线程进入运行状态...,执行任务1...
线程A正在执行任务1...
任务1——1,首先拿到锁资源A...
任务1——已拿到拿到锁资源Azyh.example.demo.java_basic.thread.sisuo.second.LockA@38b1b60f,然后利用锁资源A去做一些事情...
任务1——2,再去获取锁资源B...
任务1——已拿到拿到锁资源Bzyh.example.demo.java_basic.thread.sisuo.second.LockB@36764f69,然后利用锁资源B去做一些事情...
任务1——结束...
三,线程死锁:
有两个对象资源LockA和LockB:
public class LockA {
}
public class LockB {
}
有一个任务task1,先获取LockA,利用LockA去执行一些业务逻辑,再获取LockB,利用LockB去执行一些业务逻辑。
/**
* 任务1:
* 任务1中的任务是:1,首先拿到锁资源A,然后利用锁资源A去做一些事情...
*/
public static void task01() {
System.out.println(Thread.currentThread().getName() + "正在执行任务1...");
System.out.println("任务1——1,首先拿到锁资源A...");
synchronized (lockA) {
Thread.sleep(3000);
System.out.println("任务1——已拿到拿到锁资源A" + lockA.toString() + ",然后利用锁资源A去做一些事情...");
System.out.println("任务1——2,再去获取锁资源B...");
synchronized (lockB) {
System.out.println("任务1——已拿到拿到锁资源B" + lockB.toString() + ",然后利用锁资源B去做一些事情...");
System.out.println("任务1——结束...");
}
}
}
有一个任务task2,先获取LockB,利用LockB去执行一些业务逻辑,再获取LockA,利用LockA去执行一些业务逻辑。
/**
* 任务2:
*/
public static void task02() {
System.out.println(Thread.currentThread().getName() + "正在执行任务2...");
System.out.println("任务2——2,首先拿到锁资源B...");
synchronized (lockB) {
Thread.sleep(3000);
System.out.println("任务2——已拿到拿到锁资源B" + lockB.toString() + ",然后利用锁资源B去做一些事情...");
System.out.println("任务2——2,再去获取锁资源A...");
synchronized (lockA) {
System.out.println("任务2——已拿到拿到锁资源A" + lockA.toString() + ",然后利用锁资源A去做一些事情...");
System.out.println("任务2——结束...");
}
}
}
创建线程A和线程B去执行任务1和任务2:
线程A持有锁资源LockA,去获取锁资源B,
线程B持有锁资源LockB,去获取锁资源A,
此时线程A和线程B都想获取对方持有的锁资源,且不肯先放弃自己持有的锁资源,就导致了死锁。。。
private static LockA lockA = new LockA();
private static LockB lockB = new LockB();
public static void main(String[] args) {
//创建线程A与B:
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 线程进入运行状态...,执行任务1...");
try {
task01();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "线程A");
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 线程进入运行状态...,执行任务2...");
try {
task02();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "线程B");
//启动两个线程的start()方法,使其进入就绪状态:
threadA.start();
threadB.start();
}
打印结果:
线程B 线程进入运行状态...,执行任务2...
线程A 线程进入运行状态...,执行任务1...
线程B正在执行任务2...
线程A正在执行任务1...
任务1——1,首先拿到锁资源A...
任务2——2,首先拿到锁资源B...
任务2——已拿到拿到锁资源Bzyh.example.demo.java_basic.thread.sisuo.second.LockB@38b1b60f,然后利用锁资源B去做一些事情...
任务2——2,再去获取锁资源A...
任务1——已拿到拿到锁资源Azyh.example.demo.java_basic.thread.sisuo.second.LockA@260e4b44,然后利用锁资源A去做一些事情...
任务1——2,再去获取锁资源B...
可以看到,程序一直结束不了,陷入了死锁状态。。。