`
trydofor
  • 浏览: 150527 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

多线程情况下的一点差异

阅读更多
以下代码,没实际意义。
注意以下情况的不同点。
1)volatile 和 Atomic*
* private volatile long             unusedAmount = 0;
* private final AtomicLong          unusedAmount = new AtomicLong();
* private long                      unusedAmount  = 0;
2)作用域及异常
* nextA1()
* nextA2()
* nextB1()
* nextB2()


import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class ThinkingInSync {
    
    private final ReadWriteLock       rwLock       = new ReentrantReadWriteLock();
    private final Lock                rLock        = rwLock.readLock();
    private final Lock                wLock        = rwLock.writeLock();
    
    // sync
    private final LinkedList<Integer> readWriteBox = new LinkedList<Integer>();
    private volatile long             unusedAmount = 0;
    private volatile Integer          currentValue = null;
    
    //private final AtomicLong          unusedAmount = new AtomicLong(); // 1
    //private long                      unusedAmount  = 0; // 2
    
    //
    private final Random              random       = new Random();
    private final AtomicInteger       counter      = new AtomicInteger(0);
    
    public Integer nextA1() throws InterruptedException, TimeoutException {
        wLock.lock();
        try {
            if (readWriteBox.size() <= 0) {
                syncLoad();
                unusedAmount = readWriteBox.size();
            }
            currentValue = makeValue();
            unusedAmount--;
        }
        finally {
            wLock.unlock();
        }
        return currentValue;
    }
    
    public Integer nextA2() throws InterruptedException, TimeoutException {
        wLock.lock();
        try {
            if (readWriteBox.size() <= 0) {
                syncLoad();
                unusedAmount = readWriteBox.size();
            }
            currentValue = makeValue();
            unusedAmount--;
            return currentValue;
        }
        finally {
            wLock.unlock();
        }
    }
    
    public Integer nextB1() throws InterruptedException, TimeoutException {
        wLock.lock();
        try {
            if (readWriteBox.size() <= 0) {
                syncLoad();
                unusedAmount = readWriteBox.size();
            }
            unusedAmount--;
            currentValue = makeValue();
            return currentValue;
        }
        finally {
            wLock.unlock();
        }
    }
    
    public Integer nextB2() throws InterruptedException, TimeoutException {
        wLock.lock();
        Integer result = null;
        long varUnused = unusedAmount;
        try {
            if (readWriteBox.size() <= 0) {
                syncLoad();
                varUnused = readWriteBox.size();
            }
            result = makeValue();
            varUnused--;
        }
        finally {
            unusedAmount = varUnused;
            currentValue = result;
            wLock.unlock();
        }
        
        return result;
    }
    
    public Integer current() {
        rLock.lock();
        try {
            return currentValue;
        }
        finally {
            rLock.unlock();
        }
    }
    
    public long remains() {
        rLock.lock();
        try {
            return unusedAmount;
        }
        finally {
            rLock.unlock();
        }
    }
    
    //-------------------------------
    private Integer makeValue() throws InterruptedException, TimeoutException {
        randomEvent();
        return readWriteBox.isEmpty() ? null : readWriteBox.removeFirst();
    }
    
    private int syncLoad() throws InterruptedException, TimeoutException {
        int sleep = randomEvent();
        readWriteBox.add(counter.incrementAndGet());
        int count = 1;
        if (sleep % 2 == 0) {
            count++;
            readWriteBox.add(counter.incrementAndGet());
        }
        if (sleep % 3 == 0) {
            count++;
            readWriteBox.add(counter.incrementAndGet());
        }
        
        return count;
    }
    
    private int randomEvent() throws InterruptedException, TimeoutException {
        int sleep = random.nextInt();
        
        if (sleep > 10000) {
            Thread.sleep(5000);
            throw new TimeoutException();
        }
        else if (sleep < 100) {
            Thread.currentThread().interrupt();
            throw new InterruptedException();
        }
        else {
            Thread.sleep(sleep);
        }
        
        return sleep;
    }
}

分享到:
评论

相关推荐

    基于java实现的,以rsync算法原理为基础的二进制文件差异比较处理.zip

    - **并行处理**:可以使用多线程或异步处理来加速校验和计算和文件比较。 - **内存管理**:对于大数据文件,需谨慎处理内存使用,防止内存溢出。 - **错误处理**:确保在出现网络问题或文件损坏时,能够恢复或回滚...

    HashMap与HashTable区别

    它通过内部同步(synchronized)机制确保了多线程环境下的安全性。这意味着在多线程环境中,对`HashTable`的操作不会导致数据不一致的情况发生。 - **HashMap**: 默认是非线程安全的。如果多个线程同时访问一个`...

    Android 平凡之路

    然而,在某些情况下(如涉及多线程同步的情况下),这种重排序会导致程序行为不符合预期。`volatile`可以确保相关的读写操作不会被重排序,从而避免此类问题的发生。 3. **不保证原子性**:虽然`volatile`提供了...

    java面试题

    如果在多线程环境下使用`HashMap`,需要开发者自己来处理同步问题。这一点区别非常重要,因为它直接影响到了`HashMap`和`HashTable`在实际项目中的选择和使用方式。 #### 对null的支持 3. **对null的支持**:`...

    Java六大关键是什么你知道吗

    虽然多线程编程可以被视为一种逻辑能力的挑战,但在很多应用场景中,实际上并不需要编写多线程程序。因为在现代平台中,多线程机制已经被内置。对于开发者而言,更重要的是理解多线程的基本原理和如何确保多线程的...

    Java内存模型详解

    Java内存模型(Java Memory Model,JMM)是Java虚拟机规范中定义的一种抽象概念,它描述了Java程序中各个变量(包括实例域、静态域和数组元素)的可见性、有序性以及在多线程环境下的行为。JMM的主要目标是解决由于...

    Python语言与javascript语言的区别.docx

    - **JavaScript**:传统上不支持多线程,但在Node.js环境下引入了Worker Threads模块用于异步任务处理。 4. **并发模型**: - **Python**:支持多进程和多线程,但在单个解释器进程中,多线程受到GIL的限制。 - ...

    串口编程实践

    多线程编程是Win32环境下编写高性能应用程序的关键技术,特别是在串口通信中,可能需要同时处理数据的读写以及对串口设备状态的监控。理解同步机制有助于防止在多线程环境下发生数据竞争和状态冲突。 文档中还提到...

    prime_sum_C.rar_SUM

    5. **性能评估**:可能包括基准测试和性能分析,对比单线程与多线程执行的时间差异。 通过这个项目,开发者或学习者可以深入理解并行计算的基本原理,以及如何将这些理论应用于实际编程问题。它提供了一个实践平台...

    编写设备驱动程序

    热插拔允许在不关闭系统的情况下添加或移除硬件设备,这对服务器和工作站尤其有利。Solaris的驱动程序设计必须考虑到这一点,以支持即插即用设备的无缝接入和移除。 #### Solaris内核与设备树 Solaris内核提供了多...

    HashMap和HashTable的区别和不同

    为了在多线程环境中安全地使用`HashMap`,开发者需要自己负责同步,例如使用`Collections.synchronizedMap(new HashMap,V&gt;())`创建线程安全的`HashMap`实例。 #### 2. 允许null值 - **HashTable**: 不支持`null`键...

    JS内部事件机制之单线程原理

    JS(JavaScript)是基于单线程事件循环模型构建的语言,这一点使其与基于多线程模型的编程语言大相径庭。单线程的含义是指在JavaScript的运行环境中,只有一个主线程,所有任务都将在这条主线程上依次执行,而不会...

    读取文件并显示进度.rar

    不同的操作系统可能有不同的文件系统和权限机制,因此在编写代码时,应确保考虑到这些差异,以确保程序能在多种环境下正常运行。 总之,"读取文件并显示进度"是一项综合性的任务,它涉及到文件I/O、进度计算、用户...

    opencv简易截图程序,参考性程序,可做简易教程使用.zip

    6. **多线程**:如果截图程序需要在后台运行,可能需要使用多线程技术。OpenCV本身并不直接支持多线程,但可以在使用OpenCV的程序中引入线程库,如Python的`threading`模块,实现异步截图。 7. **事件处理**:为了...

    漫谈Wine

    - **线程模型**:两种操作系统在多线程处理方面的实现细节也有所不同。 - **系统调用**:尽管Wine尽力模拟Windows API,但在底层系统调用层面仍然存在差异。 **2. 补丁策略** - **内核补丁**:针对特定的内核差异...

    Java编程语言在计算机软件开发中的应用 (1).pdf

    3. 多线程:Java语言支持多线程编程,这使得它可以高效地处理并发操作。开发者能够在同一程序中启动多个线程来执行不同的任务,非常适合实现具有并发需求的网络应用和多任务处理。 4. 面向对象:Java是一种面向对象...

    OpenMP Intro

    为了保证多线程之间的正确性,OpenMP提供了多种同步机制: 1. **Critical Section**:确保同一时间只有一个线程能够进入临界区。使用`#pragma omp critical`指令。 ```c #pragma omp parallel { #pragma omp ...

    三通道和四通道性能差多少.docx

    四通道内存在这项测试中也表现出优于三通道的性能,这表明在多线程文件压缩任务中,四通道内存能更有效地利用处理器资源。 4. **PCMark 7**:PCMark 7是一款全面的系统性能基准测试工具,尽管四通道和三通道在测试...

Global site tag (gtag.js) - Google Analytics