Heim  >  Artikel  >  Java  >  Beispiel für die Verwendung einer Lese-/Schreibsperre für die Java-Multithread-Programmierung ReadWriteLock

Beispiel für die Verwendung einer Lese-/Schreibsperre für die Java-Multithread-Programmierung ReadWriteLock

高洛峰
高洛峰Original
2017-01-05 16:00:331548Durchsuche

Lese-/Schreibsperren: Unterteilt in Lesesperren und Schreibsperren. Lesesperren und Schreibsperren schließen sich gegenseitig aus. Sie müssen nur die entsprechende Sperre sperren. Wenn Ihr Code nur Daten liest und viele Personen gleichzeitig lesen, aber nicht gleichzeitig schreiben können, wenden Sie eine Lesesperre an. Wenn Ihr Code Daten ändert, kann nur eine Person gleichzeitig schreiben und nicht lesen Zeit, dann wenden Sie eine Schreibsperre an. Kurz gesagt, beim Lesen wird die Lesesperre und beim Schreiben die Schreibsperre verwendet!

Drei Threads lesen Daten und drei Threads schreiben Daten:
Sie können gleichzeitig lesen, Sie können nicht schreiben, während Sie lesen, Sie können nicht gleichzeitig schreiben und Sie können nicht lesen, während Sie schreiben.
Beim Lesen wird die Lesesperre gesetzt und nach dem Lesen entsperrt; beim Schreiben wird die Schreibsperre gesetzt und nach dem Schreiben entsperrt.
Beachten Sie, dass es endlich entsperrt ist.

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();
    }
  
  }
}

Entwerfen Sie ein Cache-System
Cache-System: Wenn Sie Daten abrufen möchten, müssen Sie meine öffentliche Methode „Object getData(String key)“ aufrufen. Ich möchte überprüfen, ob ich diese Daten intern habe Wenn ja, kehren Sie direkt zurück. Nachdem Sie sie gefunden haben, speichern Sie die Daten in meinem internen Speicher. Wenn jemand nach den Daten fragt, werde ich sie direkt zurückgeben es in der Datenbank. Wenn Sie Daten erhalten möchten, suchen Sie nicht nach einer Datenbank, sondern kommen Sie zu mir.

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;
  }
}

Weitere Artikel zu Java-Multithread-Programmierung mit Lese-/Schreibsperre und ReadWriteLock-Nutzungsbeispielen finden Sie auf der chinesischen PHP-Website!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn