每个对象都有个监视器,访问同步方法的线程会得到这个对象锁,其他线程只能等待
如果访问的是静态的同步方法,获得的实际上是相应的java.lang.Class的对象锁
同步的另一种写法是同步块
public void addName(String name) { synchronized(this) {//必须指明要获得哪个对象的锁,通常用于更细粒度的控制并发 lastName = name; nameCount++; } nameList.add(name); }
但同步块中要小心调用其他对象
一个线程在已经拥有这个对象锁的情况下,当然可以多次申请获取对象锁
也就是调用一个同步方法的时候,可以调用同一个对象的另一个同步方法,而无需等待
原子操作是说中间不能停止的操作,或者发生,或者不发生
以下两种属于原子读写:
1.对引用变量的读写,对原始类型的读写(但不包括long和double)
2.volatile变量(包括long,double)
原子操作无需考虑多线程错误
如果调用一个同步方法的时候,调用另一个对象的同步方法
恰巧同时,另外一个线程反过来调用,这时候肯定会死锁
两线程都拥有一个对象锁,却互相等待对方先释放
如果某个资源要消耗很长时间,而一个线程频繁大量的调用这个资源,会让别的线程经常得不到资源,进入饥饿状态
有这种线程,如果得不到资源就做出某种反应,恰巧也有另一个同样的线程相遇了
好比两个人走到了一块,你往左了他也往左,你往右他也往右,如此反复,进入活锁状态
public void guardedJoy() { // Simple loop guard. Wastes // processor time. Don't do this! while(!joy) {}//一个长期占用cpu的示例 System.out.println("Joy has been achieved!"); }
public synchronized void guardedJoy() {//推荐使用同步方法 // This guard only loops once for each special event, which may not // be the event we're waiting for. while(!joy) { try { wait();//并且在循环中加入wait() } catch (InterruptedException e) {} } System.out.println("Joy and efficiency have been achieved!"); }
当调用wait()时,会要求获得对象锁,执行wait()后,会自动释放对象锁并进入暂停状态
如果另一个线程获得这个对象锁并调用了notifyAll(),会唤醒所有等待此锁的线程
public synchronized notifyJoy() { joy = true; notifyAll(); }
第二个线程释放锁后,第一个线程则会重新获得锁,并恢复到刚才wait()的地方继续执行
notify适用于多个线程同一动作的话,随便选一个
public class Drop { // Message sent from producer // to consumer. private String message; // True if consumer should wait // for producer to send message, // false if producer should wait for // consumer to retrieve message. private boolean empty = true; public synchronized String take() {//同步方法 // Wait until message is // available. while (empty) { try { wait(); } catch (InterruptedException e) {} } // Toggle status. empty = true; // Notify producer that // status has changed. notifyAll(); return message; } public synchronized void put(String message) { // Wait until message has // been retrieved. while (!empty) { try { wait(); } catch (InterruptedException e) {} } // Toggle status. empty = false; // Store message. this.message = message; // Notify consumer that status // has changed. notifyAll(); } }
集合框架中已经有一些并发安全的结构,无需重复编码了
如果一个对象是不可更改的,当然无需考虑并发:
1.去掉所有setter方法
2.所有字段都是private final
3.不允许覆盖方法,可以声明为final类,或者改成private构造工厂模式得到实例
4.如果字段是个引用了可更改的其他对象,那么,
不要提供修改那个对象的方法,
不要传递自己给那个对象
不要存储那个对象的引用,必要的话,存储一个深拷贝
5.需要的话,生成一个自己的深拷贝,而不是本身
final public class ImmutableRGB {//一个无需考虑并发的类 // Values must be between 0 and 255. final private int red; final private int green; final private int blue; final private String name; private void check(int red, int green, int blue) { if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) { throw new IllegalArgumentException(); } } public ImmutableRGB(int red, int green, int blue, String name) { check(red, green, blue); this.red = red; this.green = green; this.blue = blue; this.name = name; } public int getRGB() { return ((red << 16) | (green << 8) | blue); } public String getName() { return name; } public ImmutableRGB invert() { return new ImmutableRGB(255 - red,//返回一个新的对象 255 - green, 255 - blue, "Inverse of " + name); } }
相关推荐
编写 parallel_for 循环需要使用 concurrency::parallel_for 算法,该算法可以将循环体中的任务分配给多个线程来执行。下面是一个简单的示例: ```cpp void parallel_matrix_multiply(double m1, double m2, double ...
2. **内存模型与内存屏障(Memory Model and Barriers)**:C++11内存模型定义了多线程环境下数据同步的行为。内存屏障用于确保特定操作的顺序,防止编译器和处理器的优化导致意外的重排序。优化可能包括更精细地...
2. **并行任务**:PPL使用任务(Task)作为基本的并行执行单元。`concurrency::task_group`类用于管理一组相关任务,可以方便地进行任务的提交、取消和等待。任务可以相互依赖,也可以并行执行,这为构建复杂的并行...
他妈的Java并发 :backhand_index_pointing_right:通过Demo演示出Java中并发问题。 :red_apple:整理Demo的原因 可以观察到的实际现象 :see-no-evil_monkey:比说说的并发原则 :speak-no-evil_monkey:更直观更可信。...
《C++ Concurrency in Action》是一本深入探讨C++并发编程的权威著作,作者是Anthony Williams。这本书通过详细的实例和源代码,引导读者理解和掌握在C++中进行并发编程的关键概念和技术。源码文件列表中提到的文件...
【标题】"08_mt_l2s_concurrency" 指的是一个关于“LINQ to SQL”的视频教程,重点可能是讲解在多线程环境下的并发控制。LINQ(Language Integrated Query,语言集成查询)是.NET Framework中的一项技术,它允许...
2. std::future与std::shared_future std::future和std::shared_future是用于线程间通信的模板类,它们通过提供对异步操作结果的访问来同步线程。 - 异步操作结果:std::future提供了一个访问异步操作结果的机制。...
我使用简单的基于Promise的API与Web Workers和其他Windows进行通信 使用post-me ,... :seedling: 无依赖性:2kb gzip捆绑包。 :test_tube: 出色的测试覆盖率。 :open_hands: 开源(MIT)演示版在此,主窗口与Web Wo
并行哈希图 概述 该存储库旨在提供一组出色的哈希映射实现,以及std :: map和std :: set的btree替代品,具有以下特征: 仅标头:无需构建,只需将parallel_hashmap目录复制到您的项目中就可以了。...
和谐使用DP按照惯用的语音引导程序生成四部分和声! >> > voiceProgression ( 'B-' , 'I I6 IV V43/ii ii V V7 I' ) 请参见的Web界面。 这是用。...WEB_CONCURRENCY= < NUM> gunicorn app执照根据。
数据库系统课件:ch15-16 Transactions & Concurrency Control.ppt
2. **同步原语**:详述std::mutex、std::lock_guard、std::unique_lock等同步工具的使用,防止数据竞争和死锁。 3. **原子操作与内存模型**:解释C++的内存模型,以及std::atomic的用法,保证多线程环境下的数据...
首先,"Java Concurrency in Practice"是Java并发编程的经典之作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书提供了一套实用的指导原则、设计模式和最佳实践,帮助Java开发者...
2. **任务的结果** `concurrency::task`对象提供了获取异步操作结果的方法。可以通过调用`get()`方法阻塞当前线程,直到任务完成并返回结果。如果需要在不阻塞的情况下检查任务是否完成,可以使用`is_done()`方法。...
2. **并行算法(Parallel Algorithms)**:PPL 扩展了 C++ STL 的算法,如 `std::transform` 和 `std::sort`,提供了并行版本,能够在多核处理器上自动并行化计算。这些并行算法通常比串行版本更快,尤其是在处理...
通过使用`concurrency::task`,我们可以编写非阻塞的代码,使得服务器能够同时处理多个客户端连接。 此外,C++ REST SDK的`json`模块提供了方便的接口,用于JSON数据的序列化和反序列化。这对于与RESTful API交互...
2. **数据备份与恢复**:QS08_DB2v8_BackupAndRecovery.pdf可能会详细讲解DB2的备份策略,包括全备、增量备份数、逻辑备份和物理备份。数据恢复涉及恢复模式、时间点恢复和故障恢复,确保在系统故障或数据丢失后能...
《C++ Concurrency in Action》是一本深入探讨C++并发编程的专业书籍,旨在帮助开发者理解和掌握多线程、异步编程以及同步机制等关键概念。这本书提供了中英文两个版本,以便不同语言背景的读者理解,并且附带了源...
其中,乐观并发控制(Optimistic Concurrency Control, OCC)是一种不同于传统的基于锁的并发控制机制的方法。 #### 乐观并发控制简介 乐观并发控制作为一种对传统两阶段锁定(2PL)方法的反应而出现。两阶段锁定...
2. **自旋锁**:在读写冲突较少时,使用自旋锁代替传统互斥锁,减少线程阻塞的时间。 3. **精细粒度的锁**:对资源进行细分,只锁定必要的部分,降低锁的粒度。 4. **乐观锁**:先进行操作,后检查冲突,如果检测到...