简体   繁体   English

使用 3 个线程按顺序打印数字

[英]Printing numbers in sequence using 3 threads

I have a program where 3 Threads are trying to print numbers in sequence from 1 to 10. I am using a CountDownLatch to keep keep a count.我有一个程序,其中 3 个线程试图按从 1 到 10 的顺序打印数字。我正在使用CountDownLatch来保持计数。

But the program stops just after printing 1.但是程序在打印 1 后就停止了。

Note: I am aware that using AtomicInteger instead of Integer can work.注意:我知道使用AtomicInteger而不是Integer可以工作。 But I am looking to find out the issue in the current code.但我希望找出当前代码中的问题。

public class Worker implements Runnable {
    private int id;
    private volatile Integer count;
    private CountDownLatch latch;

    public Worker(int id, Integer count, CountDownLatch latch) {
        this.id = id;
        this.count = count;
        this.latch = latch;
    }

    @Override
    public void run() {
        while (count <= 10) {
            synchronized (latch) {
                if (count % 3 == id) {
                    System.out.println("Thread: " + id + ":" + count);
                    count++;
                    latch.countDown();
                }
            }
        }
    }

}

Main program:主程序:

public class ThreadSequence {
    private static CountDownLatch latch = new CountDownLatch(10);
    private volatile static Integer count = 0;

    public static void main(String[] args) {
        Thread t1 = new Thread(new Worker(0, count, latch));
        Thread t2 = new Thread(new Worker(1, count, latch));
        Thread t3 = new Thread(new Worker(2, count, latch));

        t1.start();
        t2.start();
        t3.start();

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

Edited program with AtomicInteger :使用AtomicInteger编辑程序:

public class ThreadSequence {
    private static AtomicInteger atomicInteger = new AtomicInteger(1);

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new WorkerThread(0, atomicInteger));
        Thread t2 = new Thread(new WorkerThread(1, atomicInteger));
        Thread t3 = new Thread(new WorkerThread(2, atomicInteger));
        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

        System.out.println("Done with main");
    }
}


public class WorkerThread implements Runnable {
    private int id;
    private AtomicInteger atomicInteger;

    public WorkerThread(int id, AtomicInteger atomicInteger) {
        this.id = id;
        this.atomicInteger = atomicInteger;
    }

    @Override
    public void run() {
        while (atomicInteger.get() < 10) {
            synchronized (atomicInteger) {
                if (atomicInteger.get() % 3 == id) {
                    System.out.println("Thread:" + id + " = " + atomicInteger);
                    atomicInteger.incrementAndGet();
                }
            }

        }
    }
}

But the program stops just after printing 1.但是程序在打印 1 后就停止了。

No this is not what happens.不,这不是发生的事情。 None of the threads terminate.没有一个线程终止。

You have a own count field in every worker.每个工人都有自己的count字段。 Other threads do not write to this field.其他线程不写入此字段。

Therefore there is only one thread, where if (count % 3 == id) { yields true , which is the one with id = 0 .因此只有一个线程,其中if (count % 3 == id) {产生true ,即id = 0线程。 Also this is the only thread that ever modifies the count field and modifying it causes (count % 3 == id) to yield false in subsequent loop iterations, causing an infinite loop in all 3 threads.这也是唯一一个修改过count字段并修改它导致(count % 3 == id)在后续循环迭代中产生false线程,从而导致所有 3 个线程中的无限循环。

Change count to static to fix this.count更改为static以解决此问题。

Edit编辑

In contrast to Integer AtomicInteger is mutable.Integer相比, AtomicInteger是可变的。 It is a class that holds a int value that can be modified.它是一个包含可以修改的int值的类。 Using Integer every modification of the field replaces it's value, but using AtomicInteger you only modify the value inside the AtomicInteger object, but all 3 threads continue using the same AtomicInteger instance.使用Integer字段的每次修改都会替换它的值,但使用AtomicInteger您只能修改AtomicInteger对象内的值,但所有 3 个线程继续使用相同的AtomicInteger实例。

您的“计数”是每个线程的不同变量,因此在一个线程中更改它不会影响其余线程,因此他们都在等待它更改,而没有任何人可以做到。

count保持为 Worker 类中的静态成员 - 对于类中的所有对象都是通用的。

You can use below code to print sequential numbers using multiple threads -您可以使用以下代码使用多个线程打印序列号 -

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadCall extends Thread {

    private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
    private ThreadCall next;

    public void setNext(ThreadCall t) {
        this.next = t;
    }

    public void addElBQ(int a) {
        this.bq.add(a);
    }

    public ThreadCall(String name) {
        this.setName(name);
    }

    @Override
    public void run() {
        int x = 0;
        while(true) {
            try {
                x = 0;
                x = bq.take();
                if (x!=0) {
                    System.out.println(Thread.currentThread().getName() + " =>" + x);
                    if (x >= 100) System.exit(0); // Need to stop all running threads
                    next.addElBQ(x+1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int THREAD_COUNT = 10;
        List<ThreadCall> listThread = new ArrayList<>();

        for (int i=1; i<=THREAD_COUNT; i++) {
            listThread.add(new ThreadCall("Thread " + i));
        }

        for (int i = 0; i < listThread.size(); i++) {
            if (i == listThread.size()-1) {
                listThread.get(i).setNext(listThread.get(0));
            }
            else listThread.get(i).setNext(listThread.get(i+1));
        }

        listThread.get(0).addElBQ(1);

        for (int i = 0; i < listThread.size(); i++) {
            listThread.get(i).start();
        }
    }
}

I hope this will resolve your problem我希望这能解决你的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM