简体   繁体   English

Java是此类的线程安全

[英]Java is this class threadsafe

Just for me I wrote class for Google Maps v2 (Android) to organize a queue of move/zoom actions. 我只为我编写了Google Maps v2 (Android)类,以组织移动/缩放操作队列。 If you know animate action is cancelled if another animation has started while first animation is still running. 如果您知道在第一个动画仍在运行时启动了另一个动画,则动画动作将被取消。

So to avoid this issue I wrote class. 为了避免这个问题,我写了课。 It's working but I want to know is it thread safe? 它正在工作,但我想知道线程安全吗? Maybe I missed something? 也许我错过了什么? Thanks in advance. 提前致谢。

public class MapDecoratorQueue {

    private List<MapDecorator> queue = new Vector<MapDecorator>();
    private boolean isRunning = false;

    public synchronized void add(MapDecorator md) {
        if (isRunning) {
            queue.add(md);
        } else {
            queue.clear();
            queue.add(md);
            next(0);
            isRunning = true;
        }
    }

    private void next(final int pos) {
        if (queue.isEmpty()) {
            isRunning = false;
        } else {
            MapDecorator decorator = queue.get(pos);
            L.log(MapDecoratorQueue.class.getSimpleName(), "isMove: "
                    + decorator.isMove() + " isZoom: " + decorator.isZoom());
            if (decorator.isMove()) {
                decorator.map.moveCamera(decorator.move);
            }
            if (decorator.isZoom()) {
                decorator.map.animateCamera(decorator.zoom,
                        decorator.zoomDuration, new CancelableCallback() {

                            @Override
                            public void onFinish() {
                                queue.remove(pos);
                                next(pos);
                            }

                            @Override
                            public void onCancel() {
                                L.log(MapDecoratorQueue.class.getSimpleName(),
                                        "cancelled");
                                queue.clear();
                                isRunning = false;
                            }
                        });
            }
        }
    }

    public static class MapDecorator {
        private GoogleMap map = null;
        private CameraUpdate move = null;
        private CameraUpdate zoom = null;
        private int zoomDuration = 0;

        /**
         * Для передвижения камеры и анимации
         * 
         * @param move
         * @param zoom
         * @param zoomDuration
         */
        public MapDecorator(GoogleMap map, CameraUpdate move,
                CameraUpdate zoom, int zoomDuration) {
            this.map = map;
            this.move = move;
            this.zoom = zoom;
            this.zoomDuration = zoomDuration;
        }

        /**
         * Только для передвижения камеры
         * 
         * @param move
         */
        public MapDecorator(GoogleMap map, CameraUpdate move) {
            this(map, move, null, 0);
        }

        /**
         * Только для зума камеры
         * 
         * @param zoom
         * @param zoomDuration
         */
        public MapDecorator(GoogleMap map, CameraUpdate zoom, int zoomDuration) {
            this(map, null, zoom, zoomDuration);
        }

        public boolean isMove() {
            return map != null && move != null;
        }

        public boolean isZoom() {
            return map != null & zoom != null && zoomDuration >= 0;
        }

        public CameraUpdate getMove() {
            return move;
        }

        public CameraUpdate getZoom() {
            return zoom;
        }

        public int getZoomDuration() {
            return zoomDuration;
        }
    }

}

The list (Vector in your cas) is thread safe but the way isRunning was used is not. 该列表(cas中的Vector)是线程安全的,但使用isRunning的方式却不是。 You can have a race condition when a Thread tries do get an element with next method and when another tries to add one with add. 当一个Thread尝试使用next方法获取一个元素,而另一个试图通过add添加一个元素时,您可能会遇到竞争条件。 If first thread is just before setting isRunning to false and the second checks it at that point you have a problem. 如果第一个线程恰好在将isRunning设置为false之前,第二个线程在那一刻检查了您的问题。

Adding synchronized to next method will solve the issue. 将同步添加到下一个方法将解决此问题。

If in line below CancelableCallback is used asynchronously then you are in trouble as you are leaking access to next(pos) method to other threads and in that case MapDecoratorQueue is not ThreadSafe. 如果在下面的行中异步使用CancelableCallback,则您会遇到麻烦,因为您将对next(pos)方法的访问泄漏给其他线程,在这种情况下,MapDecoratorQueue不是ThreadSafe。

decorator.map.animateCamera(decorator.zoom,decorator.zoomDuration, new CancelableCallback(pos));

Anyway as per Brian Goetz :), thread safety should not depend on clients implementaion (in this case animatecamera) so Your class is not threadsafe.To make it thread safe you can make next synchronized and if you do so you dont need Vector. 无论如何,按照Brian Goetz :)的说法,线程安全不应依赖于客户端实现(在这种情况下为animatecamera),因此您的类不是线程安全的。要使其成为线程安全的,您可以使下一个同步,并且如果这样做则不需要Vector。 ArrayList will work fine. ArrayList将正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM