
分布式并发设计模式详解
在分布式开发中,除了常规的23种设计模式外,还有一些针对并发场景的常用设计模式,本文将对这些模式进行详细介绍。
1. 单例模式(singleton)
- 概念:确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
-
原理:
魔法映像企业网站管理系统下载技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
- 私有构造函数:防止外部通过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 threadlocalthreadlocal = new threadlocal (); 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 blockingqueuequeue; public producer(blockingqueue 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 queue; public consumer(blockingqueue 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 queue = new linkedblockingqueue (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() {









