内置锁(隐式锁)和显示锁

1.内置锁:
(1)原理:通过内部的一个叫做监视器锁的原理来实现的,但是监视器锁本质又是依赖于底层的操作系统的Mutes Lock来实现的,操作系统之间实现线程的切换需要从用户态转换到核心态,这个成本非常高,状态之间转换需要很长的时间,所以内置锁效率较低。

(2)如何加锁和释放锁
锁对象越小越好
内置锁获得锁和释放锁是隐式的,进入synchronized修饰的代码块就获得锁,走出就释放锁
(3)通信
wait(),notify()
wait()会立刻释放当前的锁,并进入等待状态,等待到相应的notify并重新获得锁过后才能继续执行;notify()不会立刻释放锁,必须要等待notify所在线程执行完synchronized块中的所有代码才会释放
(4)编码
模式较为简单,不必显式的加锁释放锁
(5)灵活性
一旦进入等待状态没既不能中断也不能取消,容易产生饥饿和死锁的问题
在线程调用notify方法时,会随机选择相应的对象的等待队列的一个线程将其唤醒,而不是按照FIFO(先入先出队列)。
(6)性能
与显示锁相效率较低,但是java6以后性能差别不大
2.显式锁
参考原文:http://blog.csdn.net/ghsau/article/details/7461369/
在一些内置锁无法满足需求的情况下,显式锁可以作为一种高级工具。当需要一些高级功能时才应该使用ReentrantLock,这些功能包括:可定时,可轮询,可中断,公平队列,及非块结构的锁。否则还是应该优先使用synchronized。
读写锁: ReadWriteLock

class Data {      
    private int data;// 共享数据  
    private ReadWriteLock rwl = new ReentrantReadWriteLock();     
    public void set(int data) {  
        rwl.writeLock().lock();// 取到写锁  
        try {  
            System.out.println(Thread.currentThread().getName() + "准备写入数据");  
            try {  
                Thread.sleep(20);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            this.data = data;  
            System.out.println(Thread.currentThread().getName() + "写入" + this.data);  
        } finally {  
            rwl.writeLock().unlock();// 释放写锁  
        }  
    }     
    public void get() {  
        rwl.readLock().lock();// 取到读锁  
        try {  
            System.out.println(Thread.currentThread().getName() + "准备读取数据");  
            try {  
                Thread.sleep(20);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println(Thread.currentThread().getName() + "读取" + this.data);  
        } finally {  
            rwl.readLock().unlock();// 释放读锁  
        }  
    }  
}  

public static void main(String[] args) {
         final Data data = new Data();  
            for (int i = 0; i < 3; i++) {  
                new Thread(new Runnable() {  
                    public void run() {  
                        for (int j = 0; j < 5; j++) {  
                            data.set(new Random().nextInt(30));  
                        }  
                    }  
                }).start();  
            }         
            for (int i = 0; i < 3; i++) {  
                new Thread(new Runnable() {  
                    public void run() {  
                        for (int j = 0; j < 5; j++) {  
                            data.get();  
                        }  
                    }  
                }).start();  
            }  
        }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值