Maison >Java >javaDidacticiel >Exemple d'utilisation du verrouillage en lecture-écriture de programmation multithread Java ReadWriteLock

Exemple d'utilisation du verrouillage en lecture-écriture de programmation multithread Java ReadWriteLock

高洛峰
高洛峰original
2017-01-05 16:00:331571parcourir

Verrous de lecture-écriture : divisés en verrous de lecture et verrous d'écriture. Plusieurs verrous de lecture ne s'excluent pas mutuellement. Ceci est contrôlé par le jvm lui-même. Si votre code ne lit que des données et que plusieurs personnes peuvent les lire en même temps, mais ne peuvent pas écrire en même temps, appliquez un verrou en lecture. Si votre code modifie les données, une seule personne peut écrire et ne peut pas lire en même temps ; temps, puis appliquez un verrou en écriture. Bref, le verrou en lecture est utilisé lors de la lecture, et le verrou en écriture est utilisé lors de l'écriture !

Trois threads lisent les données et trois threads écrivent des données. Exemple :
Vous pouvez lire en même temps, vous ne pouvez pas écrire en lisant, vous ne pouvez pas écrire en même temps et vous ne pouvez pas lire en écrivant.
Lors de la lecture, le verrou de lecture est appliqué et déverrouillé après la lecture ; lors de l'écriture, le verrou d'écriture est appliqué et déverrouillé après l'écriture.
A noter qu'il est enfin débloqué.

package com.ljq.test.thread;
  
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
  
/**
 * 读写锁
 *
 * @author Administrator
 *
 */
public class ReadWriteLockTest {
  public static void main(String[] args) {
    final ReadWrite rw = new ReadWrite();
    for (int i = 0; i < 3; i++) {
      new Thread() {
        public void run() {
          while (true) {
            rw.read();
          }
        }
  
      }.start();
  
      new Thread() {
        public void run() {
          while (true) {
            rw.write(new Random().nextInt(10000));
          }
        }
  
      }.start();
    }
  
  }
}
  
/**
 * 读和写要互斥,因此要把它们放在同一个类中
 *
 * @author Administrator
 *
 */
class ReadWrite {
  private Object data = null;//共享数据,只能有一个线程写该数据,但可以有多个线程同时读该数据。
  ReadWriteLock rwl = new ReentrantReadWriteLock();
  
  /**
   * 读数据
   */
  public void read() {
      
    rwl.readLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + " be ready to read data!");
      Thread.sleep((long) (Math.random() * 1000));
      System.out.println(Thread.currentThread().getName() + "have read data :" + data);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      rwl.readLock().unlock();
    }
      
  }
  
  /**
   * 写数据
   *
   * @param data
   */
  public void write(Object data) {
      
    rwl.writeLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + " be ready to write data!");
      Thread.sleep((long) (Math.random() * 1000));
      this.data = data;
      System.out.println(Thread.currentThread().getName() + " have write data: " + data);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      rwl.writeLock().unlock();
    }
  
  }
}

Concevoir un système de cache
Système de cache : si vous souhaitez obtenir des données, vous devez appeler ma méthode publique Object getData(String key). Je veux vérifier si j'ai ces données en interne. Si c'est le cas, retournez directement. Sinon, recherchez le numéro dans la base de données. Après l'avoir trouvé, stockez les données dans ma mémoire interne. La prochaine fois que quelqu'un viendra me demander les données, je renverrai directement le numéro sans avoir à chercher. dans la base de données. Si vous souhaitez obtenir des données, ne cherchez pas de base de données, venez me voir.

package com.ljq.test.thread;
  
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 {
  
  private Map<String, Object> cache = new HashMap<String, Object>();
  
  public static void main(String[] args) {
    String key = "name";
    CacheDemo cacheDemo = new CacheDemo();
    System.out.println(cacheDemo.getData(key)); //从数据库获取数据
    System.out.println(cacheDemo.getData(key)); //从缓存获取数据
    System.out.println(cacheDemo.getData(key)); //从缓存获取数据
  }
  
  private ReadWriteLock rwl = new ReentrantReadWriteLock();
  
  public Object getData(String key) {
    rwl.readLock().lock(); //上读锁
    Object value = null;
    try {
      value = cache.get(key); //先查询内部存储器中有没有要的值
      if (value == null) { //如果没有,就去数据库中查询,并将查到的结果存入内部存储器中
        //释放读锁、上写锁
        rwl.readLock().unlock();
        rwl.writeLock().lock();
        try {
          if (value == null) { //再次进行判断,防止多个写线程堵在这个地方重复写
            System.out.println("read data from database");
            value = "张三";
            cache.put(key, value);
          }
        } finally {
          //设置完成 释放写锁
          rwl.writeLock().unlock();
        }
        //恢复读写状态
        rwl.readLock().lock();
      }else{
        System.out.println("read data from cache");
      }
    } finally {
      rwl.readLock().unlock(); //释放读锁
    }
    return value;
  }
}

Pour plus d'articles liés aux exemples d'utilisation du verrouillage en lecture-écriture de la programmation multithread Java ReadWriteLock, veuillez faire attention au site Web PHP chinois !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn