`
trydofor
  • 浏览: 147211 次
  • 性别: 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;
    }
}

分享到:
评论

相关推荐

    Python中单线程、多线程和多进程的效率对比实验实例

    在这种情况下,由于磁盘I/O操作是阻塞的,线程在等待I/O完成时,其他线程可以继续执行,因此多线程在这种场景下能提高效率。实验数据显示,多线程在IO密集型任务上的执行时间相比单线程有所减少。 3. 网络请求密集...

    一个进程池的服务器程序

    if (write_pid() ) //避免同时有多个该程序在运行 return -1; if (pipe(fd1) ) { perror("pipe failed"); exit(-1); } if (s_pipe(fd2) ) { perror("pipe failed"); exit(-1); } int port = atoi(argv...

    Java内存模型详解

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

    读取文件并显示进度.rar

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

    Python高级用法(GIL锁,深拷贝,浅拷贝,私有属性,魔法属性,上下文管理器)

    GIL介绍GIL与LockGIL与多线程Python 直接赋值、浅拷贝、深拷贝私有属性魔法方法属性访问控制描述符对像构造自定义容器上下文管理对象的序列化运算符相关的魔术方法比较运算符一元运算符和函数算术运算符反算术运算符...

    Delphi简单的数据自动备份系统..rar

    9. **多线程**:为了不阻塞用户界面,备份过程可能在后台线程中执行,这需要理解和使用多线程编程,如TThread或异步编程模型。 10. **版本控制**:备份系统可能还会考虑版本控制,例如保留一定数量的历史备份,以便...

    cpp-TimeSync是C中便携式时间同步库

    6. **线程安全**:在多线程环境下,时间获取和同步操作需要保证线程安全。TimeSync库可能采用了锁或其他同步机制来确保这一点。 7. **示例代码**:TimeSync-master中的源代码可能包含了一些示例程序,演示如何使用...

    高性能存储及文件系统架构设计.pptx

    无锁编程算法可以提高多线程环境下的性能,同时文件空洞的处理和线程池的设计也是优化性能的关键。 7. **版本控制与一致性算法**:文件系统中的版本控制问题可以通过vector clock算法解决,每个操作和磁盘context都...

    VC 连珠子游戏代码分享.rar

    7. **多线程编程**:虽然是一款小型游戏,但若考虑用户交互的流畅性,可能使用多线程技术来实现游戏逻辑计算和界面更新的异步处理。 8. **调试与优化**:在VC++ 6.0环境下,开发者可能会使用调试器(如Visual ...

    c# 动态比较两个文件是否相同(VS2008)

    7. **多线程优化**:如果需要比较大量文件,可以考虑使用多线程或异步IO来提高效率。`Task.Run`或`async/await`关键字可以帮助我们实现这一点。 8. **缓存策略**:对于频繁比较的文件,可以考虑引入缓存策略,比如...

    那些颇受争议的编程观点

    12. **getters 和 setters 的滥用**:过度使用 getters 和 setters 可能会导致过度封装,而在某些情况下,直接访问成员变量并无太大问题,尤其是在单线程或无业务逻辑的场景下。 这些观点反映了编程实践中多样化的...

    jsonkit测试

    6. **线程安全**: 在多线程环境中,测试 JSONKit 的行为是十分必要的,确保在并发访问时不会出现数据不一致或崩溃的问题。 7. **兼容性测试**: 检查 JSONKit 是否兼容你的目标平台(如 iOS 版本、macOS 版本),...

    winform 初始化器性能测试源码

    5. **多线程处理**:考虑到UI线程的重要性,源码可能包含对异步初始化和线程安全性的测试。 6. **资源管理**:初始化过程中,资源的加载和释放也是影响性能的因素,源码可能会关注这一点。 7. **代码优化建议**:...

    Windows64位编程规范

    10. 进程和线程调度:64位系统提供了更多的处理器核心,因此,需要优化多线程代码,以充分利用硬件资源。同时,理解并适应64位环境下的调度策略变化。 11. 注册表和配置文件:64位应用程序通常在单独的注册表位置...

    Java面试宝典

    3. **集合框架**:包括ArrayList、LinkedList、HashSet、HashMap等容器的理解与使用,掌握List、Set、Map接口的差异,了解并发环境下集合的线程安全问题,以及对CopyOnWriteArrayList、ConcurrentHashMap等并发集合...

    第2次作业1

    线程调度则在多线程环境中,选择哪个线程在已分配给进程的CPU时间内运行。 2. 对于FCFS、RR(时间片=1)、SJF和非剥夺式优先级调度,每种算法的作业执行情况、平均周转时间和平均带权周转时间会有所不同,具体计算...

    初探传说中的setImmediate函数1

    为了缓解这个问题,开发者通常会将大任务分解为多个小任务,并使用异步调用来分批执行。 文章提到了两种常见的异步执行方式:`setTimeout`和`setImmediate`。`setTimeout`是将回调函数放入事件队列,等到当前执行栈...

    最新面试宝典 绝对好用

    此外,面试还可能涉及异常处理、集合框架、多线程、IO流、网络编程、反射、设计模式等多个领域。 总的来说,Java面试宝典覆盖了广泛的Java知识,不仅要求面试者有扎实的基础,还需要他们具备解决问题的实际能力。...

    gzip源代码gzip源代码

    6. **多线程支持**:现代版本的gzip可能还包含对多线程的支持,通过并行处理来提高压缩速度。这需要在源代码中使用适当的同步原语来防止数据竞争。 7. **兼容性**:gzip遵循POSIX标准和RFC 1952,确保在不同系统间...

    C#图片处理软件-旋转翻转等

    此外,可以利用多线程或任务并行库(TPL)提高处理速度。 9. **错误处理**: 编程过程中,应考虑异常处理,确保程序在遇到问题时能正常运行。例如,文件不存在、格式不支持等情况需要妥善处理。 10. **资源管理**...

Global site tag (gtag.js) - Google Analytics