day20Java-Thread-Lock锁以及死锁

博客
Java-(高级)

文章目录

        • Lock锁
        • 死锁

Lock锁

java.util.concurrent.locks

虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。

Lock:
		void lock(): 获取锁。
		void unlock():释放锁。  
ReentrantLock是Lock的实现类。

代码演示

public class SellTicketDemo {

    public static void main(String[] args) {
        //创建线程对象
        SellTicket st = new SellTicket();

        //创建Thread对象
        Thread t1 = new Thread(st,"窗口1");
        Thread t2 = new Thread(st,"窗口2");
        Thread t3 = new Thread(st,"窗口3");

        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

自定义类实现Runnable接口

public class SellTicket implements Runnable {
    //定义100张票
    private int ticket = 100;
    //创建Lock锁对象
    Lock lock = new ReentrantLock();

    //Lock锁写法
    @Override
    public void run() {
        while (true) {
            try {


                //开
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + (ticket--) + "张票");

                }
            } finally {
                //关
                lock.unlock();
            }
        }
    }

    //以前的写法
    /*@Override
    public void run() {
        while (true){
            synchronized (this) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + (ticket--) + "张票");

                }
            }
        }
    }*/
}

结果:

窗口1正在出售第10张票
窗口1正在出售第9张票
窗口3正在出售第8张票
窗口3正在出售第7张票
窗口3正在出售第6张票
窗口3正在出售第5张票
窗口3正在出售第4张票
窗口3正在出售第3张票
窗口3正在出售第2张票
窗口3正在出售第1张票

死锁

同步的弊端:
		A:效率低
		B:容易产生死锁

死锁:
		两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象。

举例:
		中国人,美国人吃饭案例。
		正常情况:
			中国人:筷子两支
			美国人:刀和叉
		现在:
			中国人:筷子1支,刀一把
			美国人:筷子1支,叉一把

代码演示

public class DieLockDemo {
    public static void main(String[] args) {

        //创建线程对象
        DieLock dl1 = new DieLock(true);
        DieLock dl2 = new DieLock(false);

        //启动线程
        dl1.start();
        dl2.start();
    }
}

死锁代码演示

public class DieLock extends Thread{

    private boolean flag;

    public DieLock(boolean flag) {
        this.flag = flag;
    }

    //死锁代码演示
    @Override
    public void run() {
        if (flag) {
            synchronized (MyLock.objA) { //线程tl1,进来关闭锁。
                System.out.println("if objA");
                synchronized (MyLock.objB) {//因为tl2锁已经关闭了,所以在等tl2执行完开锁。
                    System.out.println("if objB");                     
                }                                                                           
            }                                                 //出现了相互等待的情况,即死锁。                  
        } else {
            synchronized (MyLock.objB) {//线程tl2,进来关闭锁。
                System.out.println("else objB");
                synchronized (MyLock.objA) {//因为tl1锁已经关闭了,所以在等tl1执行完开锁。
                    System.out.println("else objA");
                }
            }
        }
    }
}

定义两把锁

public class MyLock {
    public static final Object objA = new Object();
    public static final Object objB=  new Object();
}

结果:出现死锁(是有可能出现)

else objB
if objA

你可能感兴趣的:(JavaSE)