Hello! 欢迎来到小浪资源网!


分布式并发设计模式有哪些及其实现原理?


分布式并发设计模式有哪些及其实现原理?

分布式并发设计模式详解

分布式开发中,除了常规的23种设计模式外,还有一些针对并发场景的常用设计模式,本文将对这些模式进行详细介绍。

1. 单例模式(singleton)

  • 概念:确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
  • 原理:

    • 私有构造函数:防止外部通过new关键字创建类的实例。
    • 静态实例变量:保存类的唯一实例。
    • 全局访问点:通常是一个静态方法,用于获取类的实例。
  • 并发代码示例:

    public class singleton {   private static volatile singleton instance;      private singleton() {       // 私有构造函数   }      public static singleton getinstance() {       if (instance == null) { // 第一次检查           synchronized (singleton.class) { // 同步锁               if (instance == null) { // 第二次检查                   instance = new singleton();               }           }       }       return instance;   } }

2. 不可变对象模式(immutable Object

  • 概念:一旦创建了一个对象,其状态就不能被修改。
  • 原理:

    • 所有属性都是final的:这意味着一旦初始化后,属性值不能被改变。
    • 不提供修改状态的方法:不可变对象不提供任何可以修改其状态的方法。
    • 通过构造函数初始化所有属性:在对象创建时,必须通过构造函数初始化所有属性。
    • 深度复制:如果对象包含可变对象,需要确保这些对象在创建时也是不可变的,或者在返回时创建它们的副本。
  • 并发代码示例:

    public final class immutableperson {   private final string name;   private final int age;    public immutableperson(string name, int age) {       this.name = name;       this.age = age;   }    public string getname() {       return name;   }    public int getage() {       return age;   }    public immutableperson setname(string newname) {       return new immutableperson(newname, age);   }    public immutableperson setage(int newage) {       return new immutableperson(name, newage);   } }

3. 线程局部存储模式(thread local storage)

  • 概念:允许在线程环境下为每个线程维护一个独立的变量副本。
  • 原理:

    • Threadlocal类:Java提供了threadlocal类来支持线程局部存储。threadlocal为每个使用该变量的线程提供独立的变量副本,通过这个副本,每个线程都可以独立地改变自己的副本而不影响其他线程的副本。
    • 副本的创建和获取:threadlocal提供了get和set方法来获取和设置当前线程的变量副本。
  • 并发代码示例:

    public class threadlocalexample {   // 定义一个threadlocal变量,用于存储线程级别的变量   private static final threadlocal<string> threadlocal = new threadlocal<string>();    public static void setthreadlocalvalue(string value) {       threadlocal.set(value);   }    public static string getthreadlocalvalue() {       return threadlocal.get();   }    public static void main(string[] args) {       // 在主线程中设置和获取threadlocal变量的值       setthreadlocalvalue("main thread value");       system.out.println("main thread value: " + getthreadlocalvalue());        // 创建一个新线程并设置和获取threadlocal变量的值       thread thread = new thread(() -> {           setthreadlocalvalue("child thread value");           system.out.println("child thread value: " + getthreadlocalvalue());       });       thread.start();   } }

4. 生产者-消费者模式(producer-consumer)

  • 概念:将数据的生成(生产者)和数据的处理(消费者)分离来解决并发问题。
  • 原理:

    • 共享数据结构:通常使用队列作为共享的数据结构,生产者将数据放入队列中,消费者从队列中取出数据。
    • 同步:生产者和消费者需要同步对共享数据结构的访问,以避免并发问题。可以使用锁、信号量、阻塞队列等机制来实现同步。
    • 阻塞和唤醒:当队列满时,生产者应该阻塞等待;当队列空时,消费者应该阻塞等待。当队列状态改变时,需要唤醒相应的生产者或消费者。
  • 并发代码示例:

    import java.util.concurrent.blockingqueue; import java.util.concurrent.linkedblockingqueue;  class producer implements runnable {   private final blockingqueue<integer> queue;    public producer(blockingqueue<integer> q) {       queue = q;   }    public void run() {       try {           for (int i = 0; i < 10; i++) {               queue.put(i);               system.out.println("produced: " + i);           }       } catch (interruptedexception ex) {           ex.printstacktrace();       }   } }  class consumer implements runnable {   private final blockingqueue<integer> queue;    public consumer(blockingqueue<integer> q) {       queue = q;   }    public void run() {       try {           while (true) {               int value = queue.take();               system.out.println("consumed: " + value);           }       } catch (interruptedexception ex) {           ex.printstacktrace();       }   } }  public class producerconsumerexample {   public static void main(string[] args) {       blockingqueue<integer> queue = new linkedblockingqueue<integer>(10);       producer producer = new producer(queue);       consumer consumer = new consumer(queue);        new thread(producer).start();       new thread(consumer).start();   } }

5. 读者-写者模式(read-write lock)

  • 概念:允许多个读者同时访问数据,但在写者访问时,其他的读者或写者都会被阻塞。
  • 原理:

    • 读写锁:使用readwritelock接口和reentrantreadwritelock类来实现。这种锁有两个锁,一个用于读操作,一个用于写操作。
    • 锁的获取和释放:读者获取读锁,写者获取写锁。读锁可以被多个读者同时持有,而写锁是独占的。
    • 锁的升级和降级:在某些情况下,可能需要从读锁升级到写锁,或者从写锁降级到读锁。
  • 并发代码示例:

    import java.util.concurrent.locks.readwritelock; import java.util.concurrent.locks.reentrantreadwritelock;  class sharedresource {   private final readwritelock readwritelock = new reentrantreadwritelock();   private final lock readlock = readwritelock.readlock();   private final lock writelock = readwritelock.writelock();   private string data;    public void read() {       readlock.lock();       try {           // 读取数据           system.out.println("reading data: " + data);       } finally {           readlock.unlock();       }   }    public void write(string newdata) {       writelock.lock();       try {           // 写入数据           data = newdata;           system.out.println("writing data: " + data);       } finally {           writelock.unlock();       }   } }  public class readwritelockexample {   public static void main(string[] args) {       sharedresource resource = new sharedresource();        // 创建多个读者线程       for (int i = 0; i < 5; i++) {           new thread(resource::read).start();       }        // 创建写者线程       new thread(() -> resource.write("new data")).start();   } }

6. 工作队列模式(worker thread)

  • 概念:将任务的提交与任务的执行分离。
  • 原理:

    • 任务队列:使用一个队列来存储提交的任务。
    • 工作者线程:创建一组后台线程作为工作者线程,它们不断地从任务队列中取出任务并执行。
    • 任务提交:客户端将任务提交到队列中,不需要关心任务的执行细节。
  • 并发代码示例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit;  class Task implements Runnable {     private final int taskId;      public Task(int taskId) {         this.taskId = taskId;     }      @Override     public void run() {

相关阅读