java - 按顺序打印线程并为每个线程设置随机 sleep 时间

标签 java multithreading

我需要编写一个程序,它创建 k 个线程(在我的例子中,除了主线程之外,还创建了 6 个线程)。通过随机抽签,为每个线程指定 0-6 秒的 sleep 时间/延迟。每个线程还被赋予一条消息(变量 msg)。延迟后,每个线程都会打印它们的消息 (msg) 以及它们的序列号(就像打印为 1:st、2:nd 等)。我需要一个共享信息,其中更新打印量(打印了多少线程),并且我还需要保护/防护对其的访问。

现在它只是以随机顺序打印线程。例如: 线程数 6 线程数 2 等等

不是线程号 1、线程号 2 等

这是迄今为止我的代码:

package threadcase;

import java.util.Random;

public class Threadcase {
    static Random rnd = new Random(System.currentTimeMillis());

    public static void main(String[] args) {
        int k = 6;

        for (int i = 1; i <= k; i++) {
            Threadclass s = new Threadclass("Thread number " + i, rnd.nextInt(10) + 1, k);
            s.start();
    }
}
package threadcase;


public class Threadclass extends Thread{

    String msg = "Here is the thread";
    int k = 0;
    int delay = 0;

    public Threadclass(String msg, int k, int delay){
        this.msg = msg;
        this.delay = delay;
        this.k = k;
    }

    @Override
    public void run() {

        // sleep certain amount of seconds/milliseconds
        try {
            Thread.sleep(1000 * delay);
        } catch (InterruptedException ie) { }


        System.out.println(msg);

    }

    public int randomdelay(int delay){
        int delay = Thread.sleep((long)(Math.random() * 1000));
    }
}

最佳答案

您可以使用 AtomicInteger 充当计数器,并调用 counter.incrementAndGet(); 以线程安全的方式递增它。
如果您希望线程按照启动顺序打印,则它们还需要一个表示其顺序的字段。至于如何同步,我会使用等待并通知功能。
你的类(class)将是这样的:

public class Threadcase {
    static Random rnd = new Random(System.currentTimeMillis());

    public static void main(String[] args) {
        int k = 6;
        AtomicInteger printCounter = new AtomicInteger(0);
        for (int i = 1; i <= k; i++) {
            ThreadClass s = new ThreadClass("Thread number " + i, i, rnd.nextInt(10) + 1, k, printCounter);
            s.start();
        }
    }
}
public class ThreadClass extends Thread {

    private String msg;
    private int id;
    private int k;
    private int delay;
    private final AtomicInteger printCounter;

    public ThreadClass(String msg, int id, int k, int delay, AtomicInteger printCounter) {
        this.msg = msg;
        this.id = id;
        this.delay = delay;
        this.k = k;
        this.printCounter = printCounter;
    }

    @Override
    public void run() {
        // sleep certain amount of seconds/milliseconds
        try {
            Thread.sleep(1000 * delay);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //synchronization before while to avoid race conditions
        synchronized (printCounter) {
            //the while loop takes care of errant signals
            while (id != printCounter.get() + 1) {
                try {
                    printCounter.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(msg);
        printCounter.incrementAndGet();
        synchronized (printCounter) {
            printCounter.notifyAll();
        }
    }
}

您需要将相同的 AtomicInteger 传递给所有线程。

关于java - 按顺序打印线程并为每个线程设置随机 sleep 时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60760329/

相关文章:

java - Access (.mdb) 文件在 servlet 写入客户端期间损坏

java - 当提供 Magnet URI 时,BitTorrent 对等点如何获取信息字典?

java - 如何访问定义它的类之外的枚举

python - 多个线程可以使用同一个端口吗

c++ - shared_ptr 交换线程安全吗?

C - pthreads 似乎只使用一个核心

Java:如果 JOptionPane.showMessageDialog() 首先出现,为什么进度条百分比会消失?

Python:在另一个线程修改字典时迭代字典

android - 创建一个在 UI 线程 Android 中更新的秒表

java - Slick2D KeyListener 无法获取输入