`

Trail: Essential Classes_Lesson: Concurrency2

 
阅读更多

每个对象都有个监视器,访问同步方法的线程会得到这个对象锁,其他线程只能等待

如果访问的是静态的同步方法,获得的实际上是相应的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 循环.doc

    编写 parallel_for 循环需要使用 concurrency::parallel_for 算法,该算法可以将循环体中的任务分配给多个线程来执行。下面是一个简单的示例: ```cpp void parallel_matrix_multiply(double m1, double m2, double ...

    我们使std :: shared_mutex快10倍

    2. **内存模型与内存屏障(Memory Model and Barriers)**:C++11内存模型定义了多线程环境下数据同步的行为。内存屏障用于确保特定操作的顺序,防止编译器和处理器的优化导致意外的重排序。优化可能包括更精细地...

    main_ppl_concurrency_

    2. **并行任务**:PPL使用任务(Task)作为基本的并行执行单元。`concurrency::task_group`类用于管理一组相关任务,可以方便地进行任务的提交、取消和等待。任务可以相互依赖,也可以并行执行,这为构建复杂的并行...

    fucking-java-concurrency::carp_streamer:简单地展示Java并发问题的案例,看看:see-no-evil_monkey:相信:monkey_face:

    他妈的Java并发 :backhand_index_pointing_right:通过Demo演示出Java中并发问题。 :red_apple:整理Demo的原因 可以观察到的实际现象 :see-no-evil_monkey:比说说的并发原则 :speak-no-evil_monkey:更直观更可信。...

    C++ Concurrency in Action 源码

    《C++ Concurrency in Action》是一本深入探讨C++并发编程的权威著作,作者是Anthony Williams。这本书通过详细的实例和源代码,引导读者理解和掌握在C++中进行并发编程的关键概念和技术。源码文件列表中提到的文件...

    08_mt_l2s_concurrency

    【标题】"08_mt_l2s_concurrency" 指的是一个关于“LINQ to SQL”的视频教程,重点可能是讲解在多线程环境下的并发控制。LINQ(Language Integrated Query,语言集成查询)是.NET Framework中的一项技术,它允许...

    C++ concurrency cheatsheet

    2. std::future与std::shared_future std::future和std::shared_future是用于线程间通信的模板类,它们通过提供对异步操作结果的访问来同步线程。 - 异步操作结果:std::future提供了一个访问异步操作结果的机制。...

    后我::envelope_with_arrow:通过简单的Promise API使用Web Worker和其他Windows

    我使用简单的基于Promise的API与Web Workers和其他Windows进行通信 使用post-me ,... :seedling: 无依赖性:2kb gzip捆绑包。 :test_tube: 出色的测试覆盖率。 :open_hands: 开源(MIT)演示版在此,主窗口与Web Wo

    parallel-hashmap:一系列仅标头,非常快速且对内存友好的hashmap和btree容器

    并行哈希图 概述 该存储库旨在提供一组出色的哈希映射实现,以及std :: map和std :: set的btree替代品,具有以下特征: 仅标头:无需构建,只需将parallel_hashmap目录复制到您的项目中就可以了。...

    harmony::musical_notes:使用DP按照惯用的语音引导程序生成四部分和声!

    和谐使用DP按照惯用的语音引导程序生成四部分和声! &gt;&gt; &gt; voiceProgression ( 'B-' , 'I I6 IV V43/ii ii V V7 I' ) 请参见的Web界面。 这是用。...WEB_CONCURRENCY= &lt; NUM&gt; gunicorn app执照根据。

    数据库系统课件:ch15-16 Transactions & Concurrency Control.ppt

    数据库系统课件:ch15-16 Transactions & Concurrency Control.ppt

    CPP-Concurrency-In-Action-2ed-2019-master.zip

    2. **同步原语**:详述std::mutex、std::lock_guard、std::unique_lock等同步工具的使用,防止数据竞争和死锁。 3. **原子操作与内存模型**:解释C++的内存模型,以及std::atomic的用法,保证多线程环境下的数据...

    Concurrent_Programming+Java Concurrency in Practice+langspec

    首先,"Java Concurrency in Practice"是Java并发编程的经典之作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书提供了一套实用的指导原则、设计模式和最佳实践,帮助Java开发者...

    用C++ concurrencytask实现异步编程(附代码实例).rar

    2. **任务的结果** `concurrency::task`对象提供了获取异步操作结果的方法。可以通过调用`get()`方法阻塞当前线程,直到任务完成并返回结果。如果需要在不阻塞的情况下检查任务是否完成,可以使用`is_done()`方法。...

    CPP-VS2012-PPL.rar_VS2012

    2. **并行算法(Parallel Algorithms)**:PPL 扩展了 C++ STL 的算法,如 `std::transform` 和 `std::sort`,提供了并行版本,能够在多核处理器上自动并行化计算。这些并行算法通常比串行版本更快,尤其是在处理...

    C++ REST SDK开发HTTP服务器

    通过使用`concurrency::task`,我们可以编写非阻塞的代码,使得服务器能够同时处理多个客户端连接。 此外,C++ REST SDK的`json`模块提供了方便的接口,用于JSON数据的序列化和反序列化。这对于与RESTful API交互...

    DB2资料数据备份,数据还原,DB2原理

    2. **数据备份与恢复**:QS08_DB2v8_BackupAndRecovery.pdf可能会详细讲解DB2的备份策略,包括全备、增量备份数、逻辑备份和物理备份。数据恢复涉及恢复模式、时间点恢复和故障恢复,确保在系统故障或数据丢失后能...

    C++ Concurrency in Action 中英文及代码

    《C++ Concurrency in Action》是一本深入探讨C++并发编程的专业书籍,旨在帮助开发者理解和掌握多线程、异步编程以及同步机制等关键概念。这本书提供了中英文两个版本,以便不同语言背景的读者理解,并且附带了源...

    Transactions: Concurrency Control and Recovery: Optimist concurrency control

    其中,乐观并发控制(Optimistic Concurrency Control, OCC)是一种不同于传统的基于锁的并发控制机制的方法。 #### 乐观并发控制简介 乐观并发控制作为一种对传统两阶段锁定(2PL)方法的反应而出现。两阶段锁定...

    object_threadsafe:我们将任何对象的线程安全性和std :: shared_mutex的速度提高10倍,以实现读取率> 85%的无锁算法的速度

    2. **自旋锁**:在读写冲突较少时,使用自旋锁代替传统互斥锁,减少线程阻塞的时间。 3. **精细粒度的锁**:对资源进行细分,只锁定必要的部分,降低锁的粒度。 4. **乐观锁**:先进行操作,后检查冲突,如果检测到...

Global site tag (gtag.js) - Google Analytics