频繁调用互斥操作——Java

       开发中遇到的问题:看到项目先前实现的代码,有一个逻辑处理,要完成两个界面的切换,而且这个两个界面的切换会共同设置系统的同一个资源的状态,且设置状态的操作(系统中间件已经做了互斥)比较耗时。先前的代码采用了新建线程来设置资源状态来保证主线程不被阻塞。这就出现了一个问题,如果频繁操作切换的话,就会出现系统资源的状态错乱。

       应用调用:

Thread call state(true);

Thread call state(false);

Thread call state(true);

Thread call state(false);

Thread call state(true);

...

Thread call state(true);

    实际执行结果:

Thread run state(true);

Thread run state(false);

Thread run state(true);

Thread run state(true);

Thread run state(false);

...

Thread run state(false); or Thread run state(true);

        执行结果可以看出,在频繁调用的时候就出现与调用顺序不对应的问题,调用结束的结果可能会是错误的。

    

        究其原因是因为只考虑了耗时操作采用线程来处理,没有对线程进行管理,造成一个操作结束后,其他等待的线程抢占运行,结果肯定会出现不对应调用的情况。

 

       解决方法:

       对于状态这种设置的处理,优先要保证状态的正确性,如果在执行true的时候,又调用设置false,再调用设置true。最终结果会是true。那么在执行第一次true的时候,来了两个操作,可以选择丢弃中间设置false的操作,来提高响应效率和保证结果正确。

       另外线程的组织管理,没有比线程池好的。

    频繁调用帮助类:  

/**
 * 如果你遇到这种场景:应用需要频繁的调用两个互斥的耗时操作,而且要保证效率与结果正确的话,这个帮助类对于你可能会有用。
 * Created by leonhover on 13-12-11.
 */
public class FrequencyTaskHelper {

    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPool = null;

    /**
     * 任务队列,大小为1
     */
    private ArrayBlockingQueue queue = new ArrayBlockingQueue<Runnable>(1);

    public FrequencyTaskHelper() {
        //创建线程池,只有一个线程在运行,采用DiscardOldestPolicy机制(采用其他也可以,因为用不到,我们手动清空任务队列)
        threadPool = new ThreadPoolExecutor(1, 1, 50, TimeUnit.SECONDS,
                queue,
                new ThreadPoolExecutor.DiscardOldestPolicy());
    }

    /**
     * 在线程池中执行操作,不一定被执行
     *
     * @param runnable 操作任务
     */
    public void execute(Runnable runnable) {
        //清空任务队列
        queue.clear();
        //在线程池中执行,如果没有任务运行则执行,要不就排队,排队后又可能被丢弃。
        threadPool.execute(runnable);
    }
}

    测试类

 /**
     * 测试任务,任务延迟有20毫秒
     */
    public static class TestOption implements Runnable {

        private String name = null;

        public TestOption(String str) {
            name = str;
        }

        @Override
        public void run() {
            System.out.println("Task " + name + " start ");
            System.out.println("Task " + name + " executed!");
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task " + name + " end ");
        }
    }

    //程序入口
    public static final void main(String[] args) {
        System.out.println("Start");
        FrequencyTaskHelper helper = new FrequencyTaskHelper();
        for (int i = 0; i < 100000; i++) {
            TestOption opt = new TestOption("opt" + i);
            helper.execute(opt);
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值