并发集合测试

场景:某个集合正在被遍历的时候,给集合加入新元素,这个时候是会抛并发修改异常还是正常?如果正常的话,能不能拿到新获取的元素?

KeySetView

public class concurrentTest {
    public static void main(String[] args) {
        Set<String> channels = ConcurrentHashMap.newKeySet();
        channels.add("haha");
        channels.add("hehe");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(1500);
                    channels.add("lulu");
                    System.out.println("add lulu:" + System.currentTimeMillis());
                } catch (InterruptedException e) {

                }
            }
        }).start();
        channels.forEach(
                s -> {
                    try {
                        Thread.sleep(2000);
                        System.out.println(s + ":" +  System.currentTimeMillis());
                    } catch (InterruptedException e) {

                    }
                }
        );


    }
}

image.jpeg

在KeySetView初始化后 遍历过程中加入的元素,都不会被访问到。

 

HashSet

    public static void main(String[] args) {
        Set<String> channels = new HashSet<>();
        channels.add("haha");
        channels.add("hehe");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(3000);
                    channels.add("lulu");
                    System.out.println("add lulu:" + System.currentTimeMillis());
                } catch (InterruptedException e) {

                }
            }
        }).start();
        channels.forEach(
                s -> {
                    try {
                        Thread.sleep(2000);
                        System.out.println(s + ":" +  System.currentTimeMillis());
                    } catch (InterruptedException e) {

                    }
                }
        );


    }

image.jpeg

 

        for (String s: channels) {
            try {
                Thread.sleep(2000);
                System.out.println(s + ":" +  System.currentTimeMillis());
            } catch (InterruptedException e) {

            }
        }

 

        Iterator<String> iter = channels.iterator();
        while (iter.hasNext()) {
            String s = iter.next();
            try {
                Thread.sleep(2000);
                System.out.println(s + ":" +  System.currentTimeMillis());
            } catch (InterruptedException e) {

            }

        }

 

    public static void main(String[] args) {
        Set<String> channels = new HashSet<>();
        channels.add("haha");
        channels.add("hehe");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(3000);
                    channels.remove("hehe");
                    System.out.println("rm hehe:" + System.currentTimeMillis());
                } catch (InterruptedException e) {

                }
            }
        }).start();
/*        channels.forEach(
                s -> {
                    try {
                        Thread.sleep(2000);
                        System.out.println(s + ":" +  System.currentTimeMillis());
                    } catch (InterruptedException e) {

                    }
                }
        );*/
/*        for (String s: channels) {
            try {
                Thread.sleep(2000);
                System.out.println(s + ":" +  System.currentTimeMillis());
            } catch (InterruptedException e) {

            }
        }*/
        Iterator<String> iter = channels.iterator();
        while (iter.hasNext()) {
            String s = iter.next();
            try {
                Thread.sleep(2000);
                System.out.println(s + ":" +  System.currentTimeMillis());
            } catch (InterruptedException e) {

            }

        }
        iter = channels.iterator();
        while (iter.hasNext()) {
            String s = iter.next();
            try {
                Thread.sleep(2000);
                System.out.println(s + ":" +  System.currentTimeMillis());
            } catch (InterruptedException e) {

            }

        }

    }

image.jpeg

 

并发锁测试

 

public class conTest1 {

    private static Object lock = new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    printC();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    printB();
                }
            }
        }).start();

    }

    public static void printA() {
        synchronized (lock) {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println("A");
                } catch (InterruptedException e) {

                }
            }

        }
    }

    public static void printB() {
        synchronized (lock) {
            System.out.println("B");
        }
    }

    public static void printC() {
        synchronized (lock) {
            System.out.println("C");
        }
    }


}
  • 相同锁对象时,B和C交替拿锁,A拿到锁后,B就执行拿不到锁了,执行不了;

  • 如果A和B拿的是不同的锁对象,那么A和B都可以执行

posted @ 2024-02-05 10:59  fjlruo  阅读(2)  评论(0编辑  收藏  举报