多线程程序设计(二)——Immutable
本文摘要了《Java多线程设计模式》一书中提及的 Immutable 模式的适用场景,并针对书中例子(若干名称有微调)给出一份 C++ 参考实现及其 UML 逻辑图,也列出与之相关的模式。
◆ 适用场景
多个线程在同时访问共享数据时,只需要读取数据而不必修改数据。
◆ 解决方案
无需使用锁机制,也不提供修改共享数据的应用程序接口(API)。
◆ 参考实现
例子模拟 3 个打印机不停地打印人的信息。
class Person
{
...
string
get_name()
{
...
}
string
get_address()
{
...
}
string
to_string() const
{
...
}
};
Person 是一个 Immutable 类,没有使用锁机制,也不提供修改其中内容的接口。
class Printer
{
...
Person const&
__person__;
...
void
run() #1
{
while (true) { #2
std::printf("%s prints %s.\n", __name__.c_str(), __person__.to_string().c_str());
std::this_thread::sleep_for(milliseconds(std::rand()%1000));
}
}
};
...
int
main(int argc, char * argv[])
{
...
Person alice("Alice", "Alaska");
Printer p1("Printer1", alice);
Printer p2("Printer2", alice);
Printer p3("Printer3", alice);
thread t1(&Printer::run, &p1);
thread t2(&Printer::run, &p2); #3
thread t3(&Printer::run, &p3);
t1.join();
t2.join(); #4
t3.join();
...
}
Printer::run() 作为线程的初始函数(#1),模拟打印机不停地打印人的信息(#2)。在主线程中启动这 3 个打印机子线程(#3)后,等待子线程完成(#4)。
以下类图展现了代码主要逻辑结构,

以下顺序图展现了线程间并发中的交互。

◆ 验证测试
笔者在实验环境一中编译代码(-std=c++11)成功后运行可执行文件,
$ g++ -std=c++11 -lpthread immutable.cpp
$ ./a.out
运行结果如下:
...
Printer1 prints [ Person: name = Alice, address = Alaska ].
Printer3 prints [ Person: name = Alice, address = Alaska ].
Printer2 prints [ Person: name = Alice, address = Alaska ].
Printer2 prints [ Person: name = Alice, address = Alaska ].
Printer1 prints [ Person: name = Alice, address = Alaska ].
Printer1 prints [ Person: name = Alice, address = Alaska ].
...
可以看到三个线程交替地打印出信息。
◆ 相关模式
- 对多个线程进行共享互斥,可以使用 Single Threaded Execution 模式。
- 想要分离“读”线程和“读”线程,可以使用 Read-Write Lock 模式。
◆ 最后
完整的代码请参考 [gitee] cnblogs/18752329 。更多模式请参考多线程程序设计。
致《Java多线程设计模式》的作者结城浩。写作中也参考了《C++并发编程实战》中的若干建议,致作者 Anthony Williams 和译者周全等。
受限于作者的水平,读者如发现有任何错误或有疑问之处,请追加评论或发邮件联系 green-pi@qq.com。作者将在收到意见后的第一时间里予以回复。 本文来自博客园,作者:green-cnblogs,转载请注明原文链接:https://www.cnblogs.com/green-cnblogs/p/18752329 谢谢!

浙公网安备 33010602011771号