频繁调用互斥操作——Java_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 频繁调用互斥操作——Java

频繁调用互斥操作——Java

 2013/12/12 16:09:19  LeonHover  程序员俱乐部  我要评论(0)
  • 摘要:开发中遇到的问题:看到项目先前实现的代码,有一个逻辑处理,要完成两个界面的切换,而且这个两个界面的切换会共同设置系统的同一个资源的状态,且设置状态的操作(系统中间件已经做了互斥)比较耗时。先前的代码采用了新建线程来设置资源状态来保证主线程不被阻塞。这就出现了一个问题,如果频繁操作切换的话,就会出现系统资源的状态错乱。应用调用:Threadcallstate(true);Threadcallstate(false);Threadcallstate(true);Threadcallstate
  • 标签: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的操作,来提高响应效率和保证结果正确。

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

? ? 频繁调用帮助类: ?

class="java">/**
 * 如果你遇到这种场景:应用需要频繁的调用两个互斥的耗时操作,而且要保证效率与结果正确的话,这个帮助类对于你可能会有用。
 * 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);
        }
    }

?

发表评论
用户名: 匿名