solitaryclown

工作线程

2021-12-28
solitaryclown

工作线程

例子

package com.huangbei.test2;


import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Slf4j(topic = "c.Test-线程池工作线程问题")
public class Test10 {
    static List<String> MENU = Arrays.asList("清水白菜", "宫保鸡丁", "红烧肉", "番茄炒鸡蛋");
    static Random RANDOM = new Random();

    static String cook() {
        return MENU.get(RANDOM.nextInt(MENU.size()));
    }

    public static void main(String[] args) {

        //创建2个线程的线程池
        //模拟服务员和厨师,服务员的工作是点餐和上菜,厨师的工作是做菜
        //一开始,两个线程都可以充当服务员和厨师的工作
        ExecutorService pool = Executors.newFixedThreadPool(2);

        pool.execute(() -> {
            log.debug("点餐...");
            //通知厨师做菜
            Future<String> food = pool.submit(() -> {
                log.debug("做菜...");
                return cook();
            });

            try {
                log.debug("上菜:{}", food.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            log.debug("点餐...");
            //通知厨师做菜
            Future<String> food = pool.submit(() -> {
                log.debug("做菜...");
                return cook();
            });

            try {
                log.debug("上菜:{}", food.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });

    }
}

运行结果 在上面的例子中,线程池的线程数量为2,而这两个线程都在执行服务员的工作,等待厨师的线程的执行结果,而由于线程池已经没有额外的线程资源,因此厨师无法做菜,而服务员线程也无法继续执行,造成了整个程序无法正常运行。

解决办法:

让服务员任务和厨师任务分别由两个线程池执行。

package com.huangbei.test2;


import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Slf4j(topic = "c.Test-线程池工作线程问题")
public class Test11 {
    static List<String> MENU = Arrays.asList("清水白菜", "宫保鸡丁", "红烧肉", "番茄炒鸡蛋");
    static Random RANDOM = new Random();

    static String cook() {
        return MENU.get(RANDOM.nextInt(MENU.size()));
    }

    public static void main(String[] args) {

        //创建2个线程的线程池
        //模拟服务员和厨师,服务员的工作是点餐和上菜,厨师的工作是做菜
        //一开始,两个线程都可以充当服务员和厨师的工作
        ExecutorService waiterPool = Executors.newFixedThreadPool(1);
        ExecutorService cookPool = Executors.newFixedThreadPool(1);

        waiterPool.execute(() -> {
            log.debug("点餐...");
            //通知厨师做菜
            Future<String> food = cookPool.submit(() -> {
                log.debug("做菜...");
                return cook();
            });

            try {
                log.debug("上菜:{}", food.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        waiterPool.execute(() -> {
            log.debug("点餐...");
            //通知厨师做菜
            Future<String> food = cookPool.submit(() -> {
                log.debug("做菜...");
                return cook();
            });

            try {
                log.debug("上菜:{}", food.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });

    }
}


上一篇 Interrupt()

Comments

Content