zoukankan      html  css  js  c++  java
  • 重入锁,非公平,公平,读写锁

    重入锁
    package com.thread.demo.safe.lock;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 重入锁
     * 
     * @author Administrator
     *
     */
    public class LockDemo1 {
        private static int count;
        private static Lock lock = new ReentrantLock();
    
        public static void main(String[] args) throws Exception {
            Thread t1 = new Thread(new MyRunnable(), "AAA");
            Thread t2 = new Thread(new MyRunnable(), "BBB");
    
            t2.start();
            Thread.sleep(2000);
            t1.start();
            
            t1.join();
            t2.join();
    
            System.out.println("最终结果为:" + count);
        }
    
        static class MyRunnable implements Runnable {
    
            public void increase() {
                // 加锁
                lock.lock();
                try {
                    count++;
                    System.out.println(Thread.currentThread().getName() + "计算中....");
                    Thread.sleep(4000);// 模拟操作耗时
                    System.out.println(Thread.currentThread().getName() + "计算完成...");
                    // throw new RuntimeException();
                } catch (NumberFormatException e) {
    
                    e.printStackTrace();
                } catch (Exception e) {
    
                    e.printStackTrace();
                } finally {
                    // 解锁
                    lock.unlock();
                }
            }
    
            public void increase1() {
                if (lock.tryLock()) {
                    try {
                        count++;
                        //System.out.println(Thread.currentThread().getName() + "计算中....");
                        Thread.sleep(1000);// 模拟操作耗时
                        System.out.println(Thread.currentThread().getName() + "计算完成...");
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        // 解锁
                        lock.unlock();
                    }
                } else {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            public void run() {
                for (int i = 0; i < 10; i++) {
                    increase1();
                }
            }
    
        }
    }
    读写锁
    package com.thread.demo.safe.lock;
    
    import java.util.Random;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    class ReadWrite {
        /* 共享数据,只能一个线程写数据,可以多个线程读数据 */
        private Object data = null;
        /* 创建一个读写锁 */
        ReadWriteLock rwlock = new ReentrantReadWriteLock();
     
        /**
         * 读数据,可以多个线程同时读, 所以上读锁即可
         */
        public void get() {
             /* 上读锁 */
             rwlock.readLock().lock();
     
             try {
                 System.out.println(Thread.currentThread().getName() + " 准备读数据!");
                 /* 休眠 */
                 Thread.sleep((long) (Math.random() * 1000));
                 System.out.println(Thread.currentThread().getName() + "读出的数据为 :" + data);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } finally {
                 rwlock.readLock().unlock();
             }
        }
     
        /**
         * 写数据,多个线程不能同时 写 所以必须上写锁
         * 
         * @param data
         */
        public void put(Object data) {
     
             /* 上写锁 */
             rwlock.writeLock().lock();
     
             try {
                 System.out.println(Thread.currentThread().getName() + " 准备写数据!");
                 /* 休眠 */
                 Thread.sleep((long) (Math.random() * 1000));
                 this.data = data;
                 System.out.println(Thread.currentThread().getName() + " 写入的数据: " + data);
     
             } catch (Exception e) {
                 e.printStackTrace();
             } finally {
                 rwlock.writeLock().unlock();
             }
        }
    }
     
    /**
     * 测试类
     * 
     */
    public class ReadWriteLockDemo {
     
        public static void main(String[] args) {
     
             /* 创建ReadWrite对象 */
             final ReadWrite readWrite = new ReadWrite();
     
             /* 创建并启动3个读线程 */
             for (int i = 0; i < 3; i++) {
                 new Thread(new Runnable() {
     
                     @Override
                     public void run() {
                          readWrite.get();
     
                     }
                 },"AAA"+i).start();
                 
                 /*创建3个写线程*/
                 new Thread(new Runnable() {
                     
                     @Override
                     public void run() {
                          /*随机写入一个数*/
                          readWrite.put(new Random().nextInt(8));
                          
                     }
                 },"BBB"+i).start();
             }
             
        }
     
    }
     读写锁的实例(缓存)
    package com.thread.demo.safe.lock;
    
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * 读写锁的实例
     * 
     * @author Administrator
     *
     */
    public class CacheDemo {
        // 创建一个缓存对象
        static Map<String, Object> cache = Collections.synchronizedMap(new HashMap<>());
        static ReadWriteLock rwLock = new ReentrantReadWriteLock();
    
        /**
         * 定义一个获取数据的方法
         */
        public Object getData(String key) {
    
            // 开启读锁
            rwLock.readLock().lock();
            
            Object value = null;
            try {
                // 获取到缓冲对象中数据
                value = cache.get(key);
                
                if (value == null) {
                    // 关闭读锁
                    rwLock.readLock().unlock();
                    // 开启写锁
                    rwLock.writeLock().lock();
                    try {
                        value = cache.get(key);
                        // 再次判断是为空
                        if (value == null) {
                            // 把数据存储到缓存中
                            System.out.println("从db获取数据"+key);
                            cache.put(key, "key的值");
                            
                        }
                    } finally {
                        // 释放写锁
                        rwLock.writeLock().unlock();
                    }
                    // 打开读锁
                    rwLock.readLock().lock();
                } 
                
                System.out.println("从缓存获取");
                value = cache.get(key);
            } finally {
                // 关闭读锁
                rwLock.readLock().unlock();
            }
    
            return value;
        }
        
        static class CacheRunnable implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName());
                    System.out.println(new CacheDemo().getData(i+""));
                }
            }
            
        }
        
        public static void main(String[] args) {
            // 放入数据
            //cache.put("1", "1111");
            //cache.put("2", 22222);
            
            for ( int i = 0; i < 3; i++) {
                new Thread(new CacheRunnable(),"AAA"+i).start();
            }
            
        }
    }
  • 相关阅读:
    详细描述一下 Elasticsearch 索引文档的过程 ?
    elasticsearch 索引数据多了怎么办,如何调优,部署 ?
    elasticsearch 了解多少,说说你们公司 es 的集群架构,索 引数据大小,分片有多少,以及一些调优手段 ?
    Dubbo 和 Dubbox 之间的区别?
    Dubbo 支持服务降级吗?
    Pipeline 有什么好处,为什么要用 pipeline?
    为什么redis 需要把所有数据放到内存中?
    你对线程优先级的理解是什么?
    在 java 中 wait 和 sleep 方法的不同?
    一个线程运行时发生异常会怎样?
  • 原文地址:https://www.cnblogs.com/sunBinary/p/10588763.html
Copyright © 2011-2022 走看看