zoukankan      html  css  js  c++  java
  • 手写读写锁

    https://www.cnblogs.com/DarrenChan/p/8619476.html

    首先我们对读写锁做一个概述:

    假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写,也就是说:读-读能共存,读-写不能共存,写-写不能共存。这就需要一个读/写锁来解决这个问题。

    package com.darrenchan.lock;
    
    /**
     * 用两个int变量实现读写锁
     * @author Think
     *
     */
    public class MyReadWriteLock {
        
        private int readcount = 0;
        private int writecount = 0;
        
        public void lockread() throws InterruptedException{
            while(writecount > 0){
                synchronized(this){
                    wait();
                }
            }
            readcount++;
            //进行读取操作
            System.out.println("读操作");
        }
        
        public void unlockread(){
            readcount--;
            synchronized(this){
                notifyAll();
            }
        }
        
        public void lockwrite() throws InterruptedException{
            while(writecount > 0){
                synchronized(this){
                    wait();
                }
            }
            //之所以在这里先++,是先占一个坑,避免读操作太多,从而产生写的饥饿等待
            writecount++;
            while(readcount > 0){
                synchronized(this){
                    wait();
                }
            }
            //进行写入操作
            System.out.println("写操作");
        }
        
        public void unlockwrite(){
            writecount--;
            synchronized(this){
                notifyAll();
            }
        }
        
        public static void main(String[] args) throws InterruptedException {
            MyReadWriteLock readWriteLock = new MyReadWriteLock();
            for(int i = 0; i < 2; i++){
                Thread2 thread2 = new Thread2(i, readWriteLock);
                thread2.start();
            }
            
            for (int i = 0; i < 10; i++) {
                Thread1 thread1 = new Thread1(i, readWriteLock);
                thread1.start();
            }
            
        }
    
    }
    
    class Thread1 extends Thread{
        public int i;
        public MyReadWriteLock readWriteLock;
        
        public Thread1(int i, MyReadWriteLock readWriteLock) {
            this.i = i;
            this.readWriteLock = readWriteLock;
        }
    
        @Override
        public void run() {
            try {
                readWriteLock.lockread();
                Thread.sleep(1000);//模拟耗时
                System.out.println("第"+i+"个读任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                readWriteLock.unlockread();
            }
        }
    }
    
    
    class Thread2 extends Thread{
        public int i;
        public MyReadWriteLock readWriteLock;
        
        public Thread2(int i, MyReadWriteLock readWriteLock) {
            this.i = i;
            this.readWriteLock = readWriteLock;
        }
    
        @Override
        public void run() {
            try {
                readWriteLock.lockwrite();
                Thread.sleep(1000);
                System.out.println("第"+i+"个写任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                readWriteLock.unlockwrite();
            }
        }
    }
    

      

    当然这是简单的,还可以进一步加深,可以参考博客:http://ifeve.com/read-write-locks/#simple

    注:以上代码在++和--的时候仍然会产生并发异常,建议用AtomicInteger类型,在硬件上保证++和--操作不会出现并发异常。

  • 相关阅读:
    Procedure execution failed 2013
    struts2总结四:Action与Form表单的交互
    JQuery中的DOM操作
    easyui提交表单数据的时候如何防止二次提交
    一句话
    字符串截取函数substr和substring的不同及其相关说明
    四句话
    JAVA定时执行任务,每天定时几点钟执行任务
    JAVA定时执行任务的三种方法
    struts2总结三:struts2配置文件struts.xml的简单总结
  • 原文地址:https://www.cnblogs.com/Andrew520/p/10886628.html
Copyright © 2011-2022 走看看