死锁条件
资源互斥
一方等待资源被阻塞,对已获得资源不释放
循环等待
介绍下使用的synchronized
关键字
可以修饰代码块
,方法
修饰方法有以下几种情况:
-
普通实例方法
:锁的的是当前对象 -
类方法
: 锁住的是类 同一时间段只有一个线程可以调用这个方法
修饰代码块有以下几种情况:
1.普通对象
:锁的的是当前对象
-
类对象
:锁住的是类 同一时间段只有一个线程可以调用这个代码块
ReentrantLock
效果和 synchronized
类似
可以控制线程顺序执行 效率会低 顺序靠内部维护的链表实现
public class Main {
private static final Object lockA = new Object();
private static final Object lockB = new Object();
public static void a() {
synchronized (lockA) {
try {
Thread.sleep(1000);
System.out.println("function a");
synchronized (lockB) {
System.out.println("function a");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void c() {
synchronized (Thread.class) {
try {
System.out.println("Thread.class-c");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void d() {
synchronized (Thread.class) {
System.out.println("Thread.class-d");
}
}
public static void d() {
synchronized (Thread.class) {
System.out.println("Thread.class");
}
}
static public class Ticket implements Runnable {
private int num = 10;
ReentrantLock lock = new ReentrantLock(true);
public void run() {
while (true) {
lock.lock();
if (num > 0) {
System.out.println(Thread.currentThread().getName() + num--);
}
lock.unlock();
}
}
}
public static void main(String[] args) {
// 演示代码块 synchronized 锁类对象
new Thread(new Runnable() {
@Override
public void run() {
c();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
d();
}
}).start();
// 演示代码块 ReentrantLock 使用
Runnable runnable = new Ticket();
new Thread(runnable).start();
new Thread(runnable).start();
try {
Thread.sleep(3000);
// 演示 死锁
new Thread(new Runnable() {
@Override
public void run() {
a();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
b();
}
}).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
打印结果
Thread.class-c
Thread.class-d
Thread-210
Thread-39
Thread-28
Thread-37
Thread-26
Thread-35
Thread-24
Thread-33
Thread-22
Thread-31
function b
function a
最后死锁无法退出
网友评论