1.Lock锁引入:
JDK1.5后新增新一代的线程同步方式:Lock锁
与采用synchronized相比,lock可提供多种锁方案,更灵活
2.代码演示
public class BuyTicketThread implements Runnable{
int ticketNum=10;
//拿来一把锁
Lock lock = new ReentrantLock();//多态 接口=实现类 可以使用不同的实现类
@Override
public void run() {
for (int i=1;i<=100;i++) {
//打开锁
lock.lock();
try{//开锁关锁可能会出现异常,用try-catch捕获异常
if (ticketNum > 0) {
System.out.println("我在" + Thread.currentThread().getName() + "买到了" + (ticketNum--) + "票");
}
}catch(Exception e){
e.printStackTrace();
}finally {
//关闭锁
lock.unlock();//就算有异常这个锁也可以得到释放
}
}
}
}
3.Lock和synchronized的区别
1.Lock是显示锁(手动开启和关闭锁,别忘记关闭锁),synchronized是隐式锁
2.Lock只有代码块锁,synchronized有代码块锁和方法锁
3.使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性(提供更多的子类)
4.优先使用顺序
Lock --同步代码块(已经进入了方法体,分配了相应资源)---同步方法(在方法体之外)
线程的同步的缺点
1.对比
线程安全,效率低
线程不安全,效率高
2.可能造成死锁
死锁
>不同的线程分别占用对方需要的同步资源不放弃,都在等对方放弃自己需要的同步资源,就形成了线程的死锁
>出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
//代码演示
public class TestDeadLock implements Runnable {
public int flag=1;
static Object o1=new Object(),o2=new Object();
@Override
public void run() {
System.out.println("flag=" + flag);
if (flag==1){
synchronized(o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o2){
System.out.println("2");
}
}
}
if (flag==0) {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("2");
}
}
}
}
public static void main(String[] args){
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 =new TestDeadLock();
td1.flag=1;
td2.flag=0;
Thread t1=new Thread(td1);
t1.start();
Thread t2= new Thread(td2);
t2.start();
}
}
解决方法:减少同步资源的定义,避免嵌套同步