在Java中打印额外行的线程

kcugc4gi  于 2022-12-02  发布在  Java
关注(0)|答案(1)|浏览(113)

我正在运行一个有线程的程序,让它们休眠一段随机的时间,然后再唤醒它们。当程序运行到末尾时,它会打印出最后一个线程已经唤醒了6次。它不会在其他线程上这样做。有人知道它为什么这样做吗?
sampleThread.java

import java.util.Random;

public class sampleThread extends Thread{
    sampleThread thread;
    Random rand = new Random();

    public void run() {

        thread = new sampleThread();
        int randSleep = rand.nextInt(1000);

        System.out.println(thread.getName() + " is sleeping for " + randSleep + " milliseconds");

        try {
            Thread.sleep(randSleep);
            System.out.println(thread.getName() + " is NOW AWAKE");

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

}

driver.java

public class driver {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        List<Future<?>> futArray = new ArrayList<>();
        ExecutorService es = Executors.newFixedThreadPool(6);

        sampleThread temp = new sampleThread();
        for (int i=0; i<120; i++) {
            Future<?> future = es.submit(temp);
            futArray.add(future);
        }

输出:

Thread-117 is sleeping for 547 milliseconds
Thread-117 is NOW AWAKE
Thread-118 is sleeping for 442 milliseconds
Thread-118 is NOW AWAKE
Thread-119 is sleeping for 182 milliseconds
Thread-119 is NOW AWAKE
Thread-120 is sleeping for 487 milliseconds
Thread-120 is NOW AWAKE
Thread-120 is NOW AWAKE
Thread-120 is NOW AWAKE
Thread-120 is NOW AWAKE
Thread-120 is NOW AWAKE
Thread-120 is NOW AWAKE

我期望它只是运行和打印时,每个人都在睡觉和完成。相反,它打印最后一个线程几次。

编辑

如果有人想知道,我改变了

public class sampleThread extends Thread{
sampleThread thread;
Random rand = new Random();

public void run() {

    thread = new sampleThread();

我没有把sampleThread thread;放在run()之外,把thread = new sampleThread();放在run()之内,而是把它们合并成一条sampleThread thread = new sampleThread();语句,然后把整行放在run中,这样似乎就解决了这个问题。

1l5u6lss

1l5u6lss1#

你在重复工作。你有120个线程的事实应该是一个提示。你创建了一个线程池,但随后运行的代码在每次提交时都创建了一个 * 额外 * 的线程。
简单的解决方案:
1.不要扩展Thread,实现Runnable,这就是您所需要的。
1.要获取线程名称,请使用Thread.currentThread().getName()
就像这样:

public static class sampleThread implements Runnable {
     Random rand = new Random();

    public void run() {

         int randSleep = rand.nextInt(1000);

        System.out.println(Thread.currentThread().getName() + " is sleeping for " + randSleep + " milliseconds");

        try {
            Thread.sleep(randSleep);
            System.out.println(Thread.currentThread().getName() + " is NOW AWAKE");

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

}

现在输出为

pool-1-thread-1 is sleeping for 526 milliseconds
pool-1-thread-6 is sleeping for 497 milliseconds
pool-1-thread-4 is sleeping for 565 milliseconds
pool-1-thread-5 is sleeping for 978 milliseconds
pool-1-thread-2 is sleeping for 917 milliseconds
pool-1-thread-3 is sleeping for 641 milliseconds
pool-1-thread-6 is NOW AWAKE
pool-1-thread-6 is sleeping for 847 milliseconds
pool-1-thread-1 is NOW AWAKE
pool-1-thread-1 is sleeping for 125 milliseconds
pool-1-thread-4 is NOW AWAKE
pool-1-thread-4 is sleeping for 884 milliseconds
pool-1-thread-3 is NOW AWAKE
pool-1-thread-3 is sleeping for 245 milliseconds
pool-1-thread-1 is NOW AWAKE
.
.
.
pool-1-thread-3 is NOW AWAKE
pool-1-thread-3 is sleeping for 863 milliseconds
pool-1-thread-5 is NOW AWAKE
pool-1-thread-6 is NOW AWAKE
pool-1-thread-4 is NOW AWAKE
pool-1-thread-1 is NOW AWAKE
pool-1-thread-2 is NOW AWAKE
pool-1-thread-3 is NOW AWAKE

显示您只使用了订购的6个线程。

相关问题