Skip to main content
DelayQueue

使用

public class DelayQueueMain {
    public static void main(String[] args) {
        var queue = new DelayQueue<DelayedUser>();
        var executorService = Executors.newFixedThreadPool(2);

        executorService.execute(() -> {
            for (int i = 0; i < 3; i++) {
                var delayedUser = new DelayedUser("name-" + i, new Random().nextInt(2000));
                queue.put(delayedUser);
                System.out.println(Thread.currentThread().getName() + " put user: " + delayedUser.name() + ", avaibleTime: " + delayedUser.avaibleTime());
                sleep(1);
            }
        });

        executorService.execute(() -> {
            for (int i = 0; i < 3; i++) {
                try {
                    var delayedUser = queue.take();
                    System.out.println(Thread.currentThread().getName() + " take user: " + delayedUser.name() + ", avaibleTime: " + delayedUser.avaibleTime());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        executorService.shutdown();
    }

    static void sleep(int seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

record DelayedUser(String name, long avaibleTime) implements Delayed {

    DelayedUser(String name, long avaibleTime) {
        this.name = name;
        this.avaibleTime = System.currentTimeMillis() + avaibleTime;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(avaibleTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return (int) (this.avaibleTime - ((DelayedUser) o).avaibleTime);
    }
}

huhxLess than 1 minutejavaConcurrency-CollectionConcurrency
原子类 Atomic

Atomic翻译成中文是原子的意思,是指一个操作是不可中断的。在多个线程一起执行的时候,能够保证一个操作一旦开始,就不会被其他线程干扰。今天我们就来学习下java中自带的一些原子类。

使用

原子类都存放在java.util.concurrent.atomic下,这里以 AtomicInteger 为例子来介绍

AtomicInteger 类常用方法



huhxAbout 1 minjavaConcurrency-CollectionConcurrency
BlockingQueue

使用

如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒。同样如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。

block-queue

下面列举一个例子:

public class BlockingQueueMain {
    static BlockingQueue<String> queue = new LinkedBlockingDeque<>();

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
        new Thread(new Consumer()).start();
    }

    static class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 4; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + " start to put, time: " + LocalDateTime.now());
                    var value = "producer" + i;
                    queue.put(value);
                    System.out.println(Thread.currentThread().getName() + " put the value " + value + ", time: " + LocalDateTime.now());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 2; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + " start to take, time: " + LocalDateTime.now());
                    System.out.println(Thread.currentThread().getName() + " take the value " + queue.take() + ", time: " + LocalDateTime.now());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

huhxAbout 3 minjavaConcurrency-CollectionConcurrency
CopyOnWriteArrayList

ReadWriteLock这个锁是读写不能同时进行,java中提供的CopyOnWriteArrayList做的更狠,读与写可以同步进行,只是写与写之间会阻塞,这样就进一步的提高读取的性能了。而关于CopyOnWriteArrayList是怎么做到如此的,正是我们这里需要解答的。

使用

当我们为CopyOnWriteArrayList创建迭代器时,我们会在调用iterator()时获得列表中数据的不可变快照。

public class CopyOnWriteArrayListMain {
    public static void main(String[] args) throws InterruptedException {
        var list = new CopyOnWriteArrayList<>(List.of("0"));

        var iterator = list.iterator();
        list.add("1");
        iterator.forEachRemaining(System.out::println);

        System.out.println(Arrays.toString(list.toArray()));
    }
}

huhxAbout 2 minjavaConcurrency-CollectionConcurrency