Loading

Lock同步_小记

使用同步机制的这种方式解决线程安全问题,但是不知道具体的锁对象在哪里添加,并且锁对象在哪里释放锁对象,对于这种情况Jdk5以后Java提供了一个更具体的锁对象:Lock
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作
*
Lock是一个接口,所以它在使用的是 ReentrantLock子实现类
*
* public void lock()获取锁。
* public void unlock()试图释放此锁

对象类
package Day21_Lock;

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

/**
 * @author Aoman_Hao
 */
public class UseLock implements Runnable{
    private int tickets=20;
    public int x=0;
    //定义一个具体的锁对象
    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
        while(true){
            try {
                lock.lock();
                if(tickets>0){
                        Thread.sleep(100);      
                    System.out.println(Thread.currentThread().getName()+"窗口出售第"+(tickets--)+"张票");
                }else{
                    break;
                }
            } catch (Exception e) {
            }
            finally{
                //释放锁对象
                lock.unlock();
            }       
        }

    }

}

测试类:
package Day21_Lock;
/**
 * @author Aoman_Hao
 */
public class LockTest {

    public static void main(String[] args) {
        UseLock UL = new UseLock();

        Thread t1 = new Thread(UL, "窗口1");
        Thread t2 = new Thread(UL, "窗口2");
        Thread t3 = new Thread(UL, "窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}
输出:
窗口1窗口出售第20张票
窗口1窗口出售第19张票
窗口1窗口出售第18张票
窗口1窗口出售第17张票
窗口1窗口出售第16张票
窗口2窗口出售第15张票
窗口2窗口出售第14张票
窗口2窗口出售第13张票
窗口3窗口出售第12张票
窗口3窗口出售第11张票
窗口3窗口出售第10张票
窗口3窗口出售第9张票
窗口3窗口出售第8张票
窗口3窗口出售第7张票
窗口3窗口出售第6张票
窗口3窗口出售第5张票
窗口3窗口出售第4张票
窗口3窗口出售第3张票
窗口3窗口出售第2张票
窗口3窗口出售第1张票

使用同步机制可以解决多线程的安全问题,但是自身也会有弊端:
* 1)同步—->执行效率低(每一个线程在抢占到CPU的执行权,会去将(门)关闭,别的线程进不来)
* 2)容易出现死锁现象
*
* 死锁线程:两个或者两个以上的线程出现了互相等待的情况,就会出现死锁!
*

classa:
public class DeadClassA {
    public void FirstClassA(){
        try {
            Thread.sleep(100);
        } catch (Exception e) {
            System.out.println("进程名:"+Thread.currentThread().getName()+"调用A的First方法内部");
        }

    }
    public void LastClassA(){
        System.out.println("A的Last方法内部");
    }
}

classb:
public class DeadClassB {
    public void FirstClassB(){
        try {
            Thread.sleep(100);
        } catch (Exception e) {
            System.out.println("进程名:"+Thread.currentThread().getName()+"调用B的first方法");
        }
    }

    public void LastClassB(){
        System.out.println("进入B的Last方法内部");
    }
}

对象类:
public class DeadLock implements Runnable {

    Object obj = new Object();
    Object obj2 = new Object();
    private boolean flag;//定义一个判断量
    public void lockflag(boolean flag){
        this.flag=flag;
    }

    @Override
    public void run() {
        if(flag){
            //先调用A类的第一个方法,在调用B类的最后一个方法
            synchronized (obj) {
                new DeadClassA().FirstClassA();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj2) {
                    new DeadClassB().LastClassB();
                }
            }

        }
        else{
            //先调用B类的第一个方法,在调用A类的最后一个方法
            synchronized (obj2) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                new DeadClassB().FirstClassB();
                synchronized (obj) {
                    new DeadClassA().LastClassA();
                }
            }
    }

    }   }
测试类:
public class DeadLockTest {

    public static void main(String[] args) {

        DeadLock DL = new DeadLock();
        DL.lockflag(true);
        Thread T1 = new Thread(DL);

        DeadLock DL2 = new DeadLock();
        DL2.lockflag(false);
        Thread T2 = new Thread(DL);

        T1.start();
        T2.start();


    }

}
posted @ 2017-12-07 15:37  AomanHao  阅读(12)  评论(0)    收藏  举报