Java ElasticSearch6入门教程 62集(千峰)

同步容器
在 Java 中,同步容器主要包括 2 类:

Vector、Stack、HashTableCollections 类中提供的静态工厂方法创建的类(由 Collections.synchronizedXxxx 等方法)
Vector 实现了 List 接口,Vector 实际上就是一个数组,和 ArrayList 类似,但是 Vector 中的方法都是 synchronized 方法,即进行了同步措施。
Stack 也是一个同步容器,它的方法也用 synchronized 进行了同步,它实际上是继承于 Vector 类。
HashTable 实现了 Map 接口,它和 HashMap 很相似,但是 HashTable 进行了同步处理,而 HashMap 没有。
同步容器的缺陷
同步容器的同步原理就是在方法上用 synchronized 修饰。那么,这些方法每次只允许一个线程调用执行。

性能问题
由于被 synchronized 修饰的方法,每次只允许一个线程执行,其他试图访问这个方法的线程只能等待。显然,这种方式比没有使用 synchronized 的容器性能要差。

安全问题
同步容器真的一定安全吗?

答案是:未必。同步容器未必真的安全。在做复合操作时,仍然需要加锁来保护。

常见复合操作如下:

迭代:反复访问元素,直到遍历完全部元素;
跳转:根据指定顺序寻找当前元素的下一个(下 n 个)元素;
条件运算:例如若没有则添加等;
不安全的示例
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: &quot;Courier New&quot; !important; font-size: 12px !important;">public class Test { static Vector<Integer> vector = new Vector<Integer>();
public static void main(String[] args) throws InterruptedException {
    while(true) {
        for (int i=0;i<10;i++)
                        vector.add(i);
        Thread thread1 = new Thread(){
            public void run() {
                for (int i=0;i<vector.size();i++)
                                        vector.remove(i);
            }
            ;
        }
        ;
        Thread thread2 = new Thread(){
            public void run() {
                for (int i=0;i<vector.size();i++)
                                        vector.get(i);
            }
            ;
        }
        ;
        thread1.start();
        thread2.start();
        while(Thread.activeCount()>10)   {
        }
    }
}
}
</pre>
public class Test {
    static Vector<Integer> vector = new Vector<Integer>();
    public static void main(String[] args) throws InterruptedException {
        while(true) {
            for (int i=0;i<10;i++)
                            vector.add(i);
            Thread thread1 = new Thread(){
                public void run() {
                    synchronized (Test.class) {
                        //进行额外的同步
                        for (int i=0;i<vector.size();i++)
                                                    vector.remove(i);
                    }
                }
                ;
            }
            ;
            Thread thread2 = new Thread(){
                public void run() {
                    synchronized (Test.class) {
                        for (int i=0;i<vector.size();i++)
                                                    vector.get(i);
                    }
                }
                ;
            }
            ;
            thread1.start();
            thread2.start();
            while(Thread.activeCount()>10)   {
            }
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/weixin_44884277/article/details/89180769
今日推荐