java锁

java锁

1.公平与非公平锁

公平锁:是指多个线程按照申请锁的顺序来获取锁,就是排队,先来后到

非公平锁:是指多个线程获取的顺序并不是按照申请锁的顺序,有可能后申请的线程先获得锁,在高并发的情况下,有可能造成优先级反转或者饥饿现象;

2.可重入锁(递归锁)

ReentrantLock/Synchronized是默认非公平可重入锁

什么是可重入锁?

指的是同一线程外层函数获得锁之后,内层递归函数仍然能够获取该锁的代码,在同一线程在外层方法获取锁的时候,进入内层方会自动获取锁

 1 public synchronized void method1(){
 2     method2();
 3 }
 4 public synchronized void method2(){
 5     
 6 }
 7  8 //在同一线程下
 9 //可重入锁,就是method1进来了,可以直接调用method2,不管它有没有锁
10 //作用:防止死锁 

 

3.自旋锁

是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗.缺点是循环会消耗cpu;

 1 public class LockDemo {
 2     AtomicReference<Thread> atomicReference = new AtomicReference<>();
 3  4     public void myLock() {
 5         Thread thread = Thread.currentThread();
 6         System.out.println(Thread.currentThread().getName() + " 进来");
 7         while (!atomicReference.compareAndSet(null, thread)) {
 8             System.out.println(Thread.currentThread().getName()+"   等待获取");
 9             try {
10                 TimeUnit.SECONDS.sleep(1);
11             } catch (InterruptedException e) {
12                 e.printStackTrace();
13             }
14         }
15         System.out.println(Thread.currentThread().getName()+"   获取成功");
16     }
17     public void unLock() {
18         Thread thread=Thread.currentThread();
19         while (!atomicReference.compareAndSet(thread, null)) {
20 21         }
22         System.out.println(Thread.currentThread().getName()+" 出去");
23     }
24 25     public static void main(String[] args) {
26         LockDemo lockDemo = new LockDemo();
27         new Thread(()->{
28             lockDemo.myLock();
29             try {
30                 TimeUnit.SECONDS.sleep(5);
31             } catch (InterruptedException e) {
32                 e.printStackTrace();
33             }
34             lockDemo.unLock();
35         },"a").start();
36 37         new Thread(()->{
38             lockDemo.myLock();
39             lockDemo.unLock();
40         },"b").start();
41     } 
42 }
43

 

运行结果:

a 进来

b 进来

b 等待获取

a 获取成功

b 等待获取

b 等待获取

b 等待获取

b 等待获取

a 出去

b 获取成功

b 出去

从结果可以看出:a线程运行结束,b线程才开始执行,但是b线程并未停止运行,而是不断的尝试获取线程,知道a线程结束,这就是自旋锁;

4.独占锁(写锁)/共享锁(读锁)/互斥锁

实例:

 1 class MyCache{//资源类
 2  3     Map<String,Object> map=new HashMap<>();
 4     private ReentrantReadWriteLock reLock=new ReentrantReadWriteLock();
 5  6  7     public void put(String key, Object value) {
 8  9        reLock.writeLock().lock();
10         try{
11             System.out.println(Thread.currentThread().getName()+"  正在写入");
12             try {
13                 TimeUnit.MILLISECONDS.sleep(500);
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }
17             map.put(key,value);
18             System.out.println(Thread.currentThread().getName()+" 写入完成");
19         }catch (Exception e){
20             e.printStackTrace();
21         }finally {
22             reLock.writeLock().unlock();
23         }
24     }
25 26     public void get() {
27 28         reLock.readLock().lock();
29         try{
30             System.out.println(Thread.currentThread().getName()+"  正在读取");
31             try {
32                 TimeUnit.MILLISECONDS.sleep(500);
33             } catch (InterruptedException e) {
34                 e.printStackTrace();
35             }
36             System.out.println(Thread.currentThread().getName()+" 读取完成");
37 38         }catch (Exception e){
39             e.printStackTrace();
40         }finally {
41             reLock.readLock().unlock();
42         }
43     }
44 45 }
46 public class ReadWriteLockDemo {
47 48 49     public static void main(String[] args) {
50         MyCache myCache = new MyCache();
51         for (int i = 0; i <5 ; i++) {
52             new Thread(()->{
53               myCache.put(Thread.currentThread().getName(),Thread.currentThread().getName());
54             },String.valueOf(i)).start();
55         }
56         try {
57             TimeUnit.SECONDS.sleep(5);
58         } catch (InterruptedException e) {
59             e.printStackTrace();
60         }
61         for (int i = 0; i <5 ; i++) {
62             new Thread(()->{
63                 myCache.get();
64             },String.valueOf(i)).start();
65         }
66     }
67 }

 

 

posted @ 2019-07-20 21:46  胡萝卜88号  阅读(144)  评论(0编辑  收藏  举报