多線程之ReadWriteLock模擬緩存(九)

錯誤案例1:java

package com.net.thread.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 
 * @Time:2017年8月23日 下午6:09:20
 * @version 1.0
 * @description 讀寫鎖模擬緩存技術 ,錯誤寫法1
 */
public class Example
{
    public static void main(String[] args)
    {
        Demo demo = new Demo();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();
    }

    static class Demo
    {
        ReadWriteLock rwl = new ReentrantReadWriteLock();
        Map<Object, Object> map = new HashMap<Object, Object>();
        boolean flag;
        
        public Object get(Object key)
        {
            rwl.readLock().lock();

            Object value = null;
            value = map.get(key);
            
            //if不安全,若是在這裏邊的value依舊是null,則根本沒有安全保障                
            if (value == null) {
                flag = false;
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                if (!flag) {
                    value =  null;
                    map.put(key, value);
                    flag = true;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                rwl.writeLock().unlock();
                rwl.readLock().lock();
            }

            rwl.readLock().unlock();
            return value;
        }
    }

}

 

錯誤案例2: 在前一個案例中進行改造,但不徹底;此例子中的flag是局部變量,而局部變量其實是線程安全,就至關於每一個線程開始都有一個flag=false的結果,所以,屢次調用,屢次初始化,並無起到緩存的做用緩存

package com.net.thread.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 
 * @Time:2017年8月23日 下午6:09:20
 * @version 1.0
 * @description 讀寫鎖模擬緩存技術,錯誤寫法2
 */
public class Example2
{
    public static void main(String[] args)
    {
        Demo demo = new Demo();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();
    }

    static class Demo
    {
        ReadWriteLock rwl = new ReentrantReadWriteLock();
        Map<Object, Object> map = new HashMap<Object, Object>();
        int i = 1;
        
        public Object get(Object key)
        {
            boolean flag = false;
            rwl.readLock().lock();
            Object value = map.get(key);
            while (value == null) 
            {
                System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                if (!flag) 
                {
                    map.put(key, "初始化");
                    flag = true;
                    System.out.println(Thread.currentThread().getName() + "寫完後的flag :" + flag + " 次數:" + i);
                    i++;
                }
                rwl.writeLock().unlock();
                rwl.readLock().lock();
                value = map.get(key);
            }
            
            rwl.readLock().unlock();
            return value;
        }
    }
}

 

正確寫法:安全

package com.net.thread.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 
 * @Time:2017年8月23日 下午6:09:20
 * @version 1.0
 * @description 讀寫鎖模擬緩存技術,正確寫法
 */
public class Example3
{
    public static void main(String[] args)
    {
        Demo demo = new Demo();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(demo.get("java"));
            }
        }).start();
    }

    static class Demo
    {
        ReadWriteLock rwl = new ReentrantReadWriteLock();
        Map<Object, Object> map = new HashMap<Object, Object>();
        int i = 1;
        boolean flag = false;
        
        public Object get(Object key)
        {
            rwl.readLock().lock();
            Object value = map.get(key);
            while (value == null) 
            {
                System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                if (!flag) 
                {
                    map.put(key, "初始化");
                    flag = true;
                    System.out.println(Thread.currentThread().getName() + "寫完後的flag :" + flag + " 次數:" + i);
                    i++;
                }
                rwl.writeLock().unlock();
                rwl.readLock().lock();
                value = map.get(key);
            }
            
            rwl.readLock().unlock();
            return value;
        }
    }
}
相關文章
相關標籤/搜索