1.死锁
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块拥有“两个以上对象的锁”时,就可能发生死锁的问题。
例1
程序一致处于等待状态,陷入死锁
package Demo05;
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持状态
public class DeadLock {
public static void main(String[] args) {
Makeup gril1 = new Makeup(0, "gril1");
Makeup gril2 = new Makeup(1, "gril2");
gril1.start();
gril2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;//选择物品
String name;//使用化妆品的人
public Makeup(int choice, String name) {
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void makeup() throws InterruptedException {
if(choice==0){
synchronized (lipstick){ //获得口供的锁
Thread.sleep(1000);
System.out.println("获得口供的锁");
synchronized (mirror){ //获得镜子的锁
Thread.sleep(1000);
System.out.println("获得镜子的锁");
}
}
}
else {
synchronized (mirror){
Thread.sleep(1000);
System.out.println("获得镜子的锁");
synchronized (lipstick){ //获得口供的锁
Thread.sleep(1000);
System.out.println("获得口红的锁");
}
}
}
}
}
例2 对于例1中死锁的改进
package Demo05;
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持状态
public class DeadLock {
public static void main(String[] args) {
Makeup gril1 = new Makeup(0, "gril1");
Makeup gril2 = new Makeup(1, "gril2");
gril1.start();
gril2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;//选择物品
String name;//使用化妆品的人
public Makeup(int choice, String name) {
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void makeup() throws InterruptedException {
if(choice==0){
synchronized (lipstick){ //获得口供的锁
Thread.sleep(1000);
System.out.println("获得口红的锁");
}
synchronized (mirror){ //获得镜子的锁
Thread.sleep(1000);
System.out.println("获得镜子的锁");
}
}
else {
synchronized (mirror){
Thread.sleep(1000);
System.out.println("获得镜子的锁");
}
synchronized (lipstick){ //获得口供的锁
Thread.sleep(1000);
System.out.println("获得口红的锁");
}
}
}
}
2. Lock(锁)
- 从JDK5.0开始,Java提供了更强大的线程同步机制—通过显示定义同步锁对象来实现同步。同步锁使用Lock对象充当。
- java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应鲜活的Lock对象
- ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显示加锁、释放锁
例3
package Demo05;
import java.util.concurrent.locks.ReentrantLock;
//测试Lock锁
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2,"anna").start();
new Thread(testLock2,"kim").start();
new Thread(testLock2,"jick").start();
}
}
class TestLock2 implements Runnable{
int tickNum = 10;
//定义lock锁
private final ReentrantLock reentrantLock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
reentrantLock.lock();//加锁
if(tickNum>0){
System.out.println(Thread.currentThread().getName()+"拿到了第"+tickNum--+"票");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}
}finally {
reentrantLock.unlock();//解锁
}
}
}
}
博客主要围绕Java线程展开,介绍了死锁的概念,即多个线程互相等待对方释放资源而停止执行,还给出死锁示例及改进方法。同时阐述了从JDK5.0开始Java提供的更强大线程同步机制——Lock锁,介绍了Lock接口及常用的ReentrantLock类。

被折叠的 条评论
为什么被折叠?



