11_06.【Java】Lock锁

本文介绍了Java中Lock锁的特点,它允许在等待锁时设定超时并自动放弃,增强了线程安全性。同时,讨论了线程通过join方法争取CPU资源的优先执行,并提醒注意死锁问题,分析了死锁产生的原因和示例。
摘要由CSDN通过智能技术生成

一、Lock锁

JDK5之后有了Lock锁,Lock锁和synchronized锁的主要区别是Lock锁可以在等待很长时间锁还没释放而自动放弃锁,synchronized锁是JVM层实现的,所以系统可以知道锁是什么时候释放的,而Lock锁是代码实现的,所以一般在代码的finally处添加unlock方法:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SellThread implements Runnable {
	private int num = 25;
	private Lock rLock = new ReentrantLock(); //创建锁对象
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		rLock.lock(); //锁住
		try {
			while(true) {
				if(num>0) {
			        try {
			          Thread.sleep(300);//卖一会儿休息一会儿
			          System.out.println(Thread.currentThread().getName()+"帮多啦A梦卖第"+num--+"个铜锣烧");
			        }catch(InterruptedException e) {
			          e.printStackTrace();
			        }
				}	
			}
		}
		finally{
			rLock.unlock();    //释放锁
		}
	}
}
public class SellTest {
	public static void main(String[] args) throws InterruptedException {
		
		SellThread t = new SellThread();
		
		Thread daxiong = new Thread(t,"大雄");
		Thread xiaojing = new Thread(t,"小静");
		Thread panghu = new Thread(t,"胖虎");
		
		daxiong.start();
		xiaojing.start();
		panghu.start();
	}
}
Console:
大雄帮多啦A梦卖第25个铜锣烧
大雄帮多啦A梦卖第24个铜锣烧
大雄帮多啦A梦卖第23个铜锣烧
大雄帮多啦A梦卖第22个铜锣烧
大雄帮多啦A梦卖第21个铜锣烧
大雄帮多啦A梦卖第20个铜锣烧
大雄帮多啦A梦卖第19个铜锣烧
大雄帮多啦A梦卖第18个铜锣烧
大雄帮多啦A梦卖第17个铜锣烧
大雄帮多啦A梦卖第16个铜锣烧
大雄帮多啦A梦卖第15个铜锣烧
大雄帮多啦A梦卖第14个铜锣烧
大雄帮多啦A梦卖第13个铜锣烧
大雄帮多啦A梦卖第12个铜锣烧
大雄帮多啦A梦卖第11个铜锣烧
大雄帮多啦A梦卖第10个铜锣烧
大雄帮多啦A梦卖第9个铜锣烧
大雄帮多啦A梦卖第8个铜锣烧
大雄帮多啦A梦卖第7个铜锣烧
大雄帮多啦A梦卖第6个铜锣烧
大雄帮多啦A梦卖第5个铜锣烧
大雄帮多啦A梦卖第4个铜锣烧
大雄帮多啦A梦卖第3个铜锣烧
大雄帮多啦A梦卖第2个铜锣烧
大雄帮多啦A梦卖第1个铜锣烧

这样也可以提高线程的安全性,但是需要注意线程的死锁问题。

二、线程的优先执行

在指定的线程启动后,使用join方法使线程具有优先抢占CPU资源的权利

public class SellTest {
	public static void main(String[] args) throws InterruptedException {
		
		SellThread t = new SellThread();
		
		Thread daxiong = new Thread(t,"大雄");
		Thread xiaojing = new Thread(t,"小静");
		Thread panghu = new Thread(t,"胖虎");
		
		daxiong.start();
		daxiong.join();//让这个线程优先执行,可以使用join,但是最终能否优先不一定
		xiaojing.start();
		panghu.start();
	}
}
Console:

大雄帮多啦A梦卖第25个铜锣烧
大雄帮多啦A梦卖第24个铜锣烧
大雄帮多啦A梦卖第23个铜锣烧
大雄帮多啦A梦卖第22个铜锣烧
大雄帮多啦A梦卖第21个铜锣烧
大雄帮多啦A梦卖第20个铜锣烧
大雄帮多啦A梦卖第19个铜锣烧
大雄帮多啦A梦卖第18个铜锣烧
大雄帮多啦A梦卖第17个铜锣烧
大雄帮多啦A梦卖第16个铜锣烧
大雄帮多啦A梦卖第15个铜锣烧
大雄帮多啦A梦卖第14个铜锣烧
大雄帮多啦A梦卖第13个铜锣烧
大雄帮多啦A梦卖第12个铜锣烧
大雄帮多啦A梦卖第11个铜锣烧
大雄帮多啦A梦卖第10个铜锣烧
大雄帮多啦A梦卖第9个铜锣烧
大雄帮多啦A梦卖第8个铜锣烧
大雄帮多啦A梦卖第7个铜锣烧
大雄帮多啦A梦卖第6个铜锣烧
大雄帮多啦A梦卖第5个铜锣烧
大雄帮多啦A梦卖第4个铜锣烧
大雄帮多啦A梦卖第3个铜锣烧
大雄帮多啦A梦卖第2个铜锣烧
大雄帮多啦A梦卖第1个铜锣烧

上述是某一次执行的结果,具体join线程能否抢占资源成功,结果是不一定的。

三、死锁

出现死锁问题是因为对象在执行同步代码的时候,出现相互等待的情况,比如:

public class MyLock {
	public static Object obj1 = new Object();
	public static Object obj2 = new Object();

}
public class DeadLockDemo extends Thread{
	private boolean flag;
	
	public DeadLockDemo(boolean flag) {
	this.flag = flag;
	}
	
	public void run() {
		while(true) {
			if(flag) {
				synchronized(MyLock.obj1) {
					System.out.println("if语句用的是obj1的锁");
					synchronized(MyLock.obj2) {
						System.out.println("if语句用的是obj2的锁");
					}
				}
			}
			else {
				synchronized(MyLock.obj2) {
					System.out.println("else语句用的是obj2的锁");
					synchronized(MyLock.obj1) {
						System.out.println("else语句用的是obj1的锁");
					}
				}			
			}
		}
	}
	
}
public class LockTest {
	public static void main(String[] args) {
		DeadLockDemo deadLockDemo = new DeadLockDemo(true);
		DeadLockDemo deadLockDemo2 = new DeadLockDemo(false);
	
		deadLockDemo.start();
		deadLockDemo2.start();
		
	}

}
Console:

if语句用的是obj1的锁
else语句用的是obj2的锁

这时候就出现死锁的情况,他们在互相等待。

线程是具有随机性的,哪一个线程先抢到cpu的执行权,它就会被先执行。如果想要控制一个线程,让其先执行,就需要使用守护线程了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值