【问题标题】:Doesn't executor service in java submits tasks parallelly?java中的执行器服务不是并行提交任务吗?
【发布时间】:2017-08-20 02:57:41
【问题描述】:

我在玩 java 多线程代码。我创建了一个带有固定线程池的执行器服务。我按顺序提交两个任务。我试图用 Thread.sleep 让第一个任务变得很长。我在想这两个任务将并行运行。但是,当我运行程序时,程序会等待一段时间,然后打印 A B,这意味着编译器首先完成了第一个任务,然后再执行第二个任务。其实,我是期待的,因为第二个任务是一个短任务,它会在第一个任务之前完成。请解释一下?

 public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    Map<String, String> map = new HashMap<>();
    ReadWriteLock lock = new ReentrantReadWriteLock();
    executor.submit(() -> {
        lock.writeLock().lock();
        try {
            Thread.sleep(10000);
            map.put("boo", "mar");
            System.out.println("A");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    });

    executor.submit(() -> {
        lock.writeLock().lock();
        try {
            Thread.sleep(1);
            map.put("foo", "bar");
            System.out.println("B");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    });

    executor.shutdown();
}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    您在第一个线程休眠之前“锁定”writeLock.. 所以锁实际上被锁定了 10 秒.. 然后它被解锁。第二个线程等待 10 秒来获取锁。

    事件顺序:

    Thread 1: Starts
    Thread 2: Starts
    
    Thread 1: Acquire Lock and wait for 10 seconds.
    Thread 2: Try to acquire lock (ends up waiting 10 seconds because it is already acquired by Thread 1).
    
    Thread 1: Prints Data.
    Thread 1: Unlocks lock.
    
    Thread 2: Acquires lock.
    Thread 2: Prints data.
    Thread 2: Unlocks lock.
    

    试试下面的方法(它只在必要时获取锁.. IE:在执行写操作或修改地图时):

    public static void main(String[] args) {
            ExecutorService executor = Executors.newFixedThreadPool(10);
            Map<String, String> map = new HashMap<>();
            ReadWriteLock lock = new ReentrantReadWriteLock();
            executor.submit(() -> {
                try {
                    Thread.sleep(10000);
    
                    lock.writeLock().lock();
                    map.put("boo", "mar");
                    lock.writeLock().unlock();
    
                    System.out.println("A");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            executor.submit(() -> {
                try {
                    Thread.sleep(1);
    
                    lock.writeLock().lock();
                    map.put("foo", "bar");
                    lock.writeLock().unlock();
    
                    System.out.println("B");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            executor.shutdown();
        }
    

    【讨论】:

    • 谢谢布兰登!这是非常好的和精确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多