多线程-内置锁、显式锁、公平锁、非公平锁

synchronized :代码简洁,隐式支持可重新获得锁

synchronized就不实现了,大家可以自行尝试

Lock:获取锁可以被中断,超时获取锁,尝试获取锁

Lock锁的运用更加灵活

这里我们用可重入锁的实例来实现:Lock lock = new ReentrantLock();(注意,这里我们可以观察ReentrantLock里面)

 这一段话意味着,我们在构造锁实例的时候,可以给他设置是否为公平锁还是非公平锁,默认是非公平锁,设置ture为公平锁

 公平锁和非公平锁(面试可能会问)

 如果在时间上,先对锁进行获取的请求,一定先被满足,这个锁就是公平的,不满足,就是非公平的,公平锁

 从理论来说,可以认为非公平锁速度更快,可以从CPU的时间片轮转机制来理解

/**
 *类说明:测试Lock和Condition实现等待通知
 */
public class TestCond {
    private static ExpressCond express = new ExpressCond(0,ExpressCond.CITY);

    /*检查里程数变化的线程,不满足条件,线程一直等待*/
    private static class CheckKm extends Thread{
        @Override
        public void run() {
        	express.waitKm();
        }
    }

    /*检查地点变化的线程,不满足条件,线程一直等待*/
    private static class CheckSite extends Thread{
        @Override
        public void run() {
        	express.waitSite();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for(int i=0;i<3;i++){
            new CheckSite().start();
        }
        for(int i=0;i<3;i++){
            new CheckKm().start();
        }

        Thread.sleep(1000);
        express.changeKm();//快递里程变化
    }
}

/**
 *类说明:实现Lock的可重入锁,展示Condition的await()、signal()灵活性与Object的notify()唤醒可能被其他线程拦截差异
 */
public class ExpressCond {
    public final static String CITY = "ShangHai";
    private int km;/*快递运输里程数*/
    private String site;/*快递到达地点*/
    private Lock lock = new ReentrantLock();
    private Condition keCond = lock.newCondition();
    private Condition siteCond = lock.newCondition();

    public ExpressCond() {
    }

    public ExpressCond(int km, String site) {
        this.km = km;
        this.site = site;
    }

    /* 变化公里数,然后通知处于wait状态并需要处理公里数的线程进行业务处理*/
    public void changeKm(){
        lock.lock();
        try {
        	this.km = 101;
        	keCond.signalAll();
        }finally {
        	lock.unlock();
        }
    }

    /* 变化地点,然后通知处于wait状态并需要处理地点的线程进行业务处理*/
    public  void changeSite(){
    	lock.lock();
        try {
        	this.site = "BeiJing";
        	siteCond.signal();
        }finally {
        	lock.unlock();
        }    	
    }

    /*当快递的里程数大于100时更新数据库*/
    public void waitKm(){
    	lock.lock();
    	try {
        	while(this.km<=100) {
        		try {
        			keCond.await();
    				System.out.println("check km thread["+Thread.currentThread().getId()
    						+"] is be notifed.");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        	}    		
    	}finally {
    		lock.unlock();
    	}

        System.out.println("the Km is "+this.km+",I will change db");
    }

    /*当快递到达目的地时通知用户*/
    public void waitSite(){
    	lock.lock();
        try {
        	while(CITY.equals(this.site)) {
        		try {
        			siteCond.await();
    				System.out.println("check site thread["+Thread.currentThread().getId()
    						+"] is be notifed.");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        	}
        }finally {
        	lock.unlock();
        } 
        System.out.println("the site is "+this.site+",I will call user");
    }
}

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_42709262/article/details/88982865