两个问题,1、是线程一直没有结束,2、System.out.println("--------------dataNum = " + dataNum);这句输出的值也不争确,请指教.

public class T05_ThreadPool {
public static void main(String[] args) throws InterruptedException {
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>();
for (int i = 0; i < 10000; i++) {
queue.offer(i);
}
AtomicInteger dataNum = new AtomicInteger(0);
ExecutorService service = Executors.newFixedThreadPool(8); //execute submit
int queueSize = queue.size();
for (int i = 0; i < queueSize; i++) {
service.execute(new Runnable(){
@Verride
public void run(){
try{
if(!queue.isEmpty()){
System.out.println("-------" + queue.poll() + "-------");
TimeUnit.MILLISECONDS.sleep(500);
dataNum.addAndGet(1);
}else{
service.shutdown();
System.out.println("--------------dataNum = " + dataNum);
}

                    }catch(Exception e){
                        e.printStackTrace();
                        service.shutdown();
                }
            }
        });
    }

    System.out.println(service);
}

}

队列中一共一万个元素,你建立了一个线程池,8个线程,循环一万次也始终是这8个线程在处理,最后一个元素被某一个线程处理完后,队列虽然为空了,但你的for循环也完了,没有调用shutdown结束线程,多循环一次就可以了。
输出结果不对,你在service.shutdown();前面加一个线程休眠,让执行中的线程执行完毕,结果自然就对了,线程shutdown是立即执行,即使有正在执行中的线程。
若解决了你的疑问,望采纳,若还有疑问可以提出

第一个问题,线程池的 shutdown 没有执行,是因为你刚刚提交了跟队列元素一样的任务,刚刚所有任务执行时正好 poll 一个元素,执行的时候队列都是有元素的。
应该用比队列元素多一点的线程任务,才可能在队列空的时候关闭线程池。

for (int i = 0; i < queueSize+2; i++) {//任务数比队列元素多一点,就能保证线程池被关闭了。

第二个问题,楼主贴的代码,是不可能执行到 else 分支打印 dataNum 的。但是如果在 if 分支中打印,dataNum 的确不正确。AtomicInteger 类时线程安全的,能够保证计数的正确,程序打印不准确,是因为其他线程有休眠动作,没有执行后面的 increase 时线程池就已经关闭了。