序号使用线程同步

Sequence number using thread Synchronization

我想使用 n 个线程打印一系列 1 到 100 的数字(为此我们使用 10 个线程)。条件是第一个线程的序列号为 1、11,21....91,第二个线程的序列号为 2,12,22.....92,依此类推。所有其他线程都将具有这样的序列号。现在我想按 1 到 100 的顺序打印数字。我知道我们可以使用同步、等待和通知方法以及使用变量或标志计数器,但我认为这不是使用它的好主意。我想在没有并发的情况下使用(如执行程序等)我将如何做到这一点。请提出建议。

public class PrintNumberSequenceUsingRunnable {
    int notifyValue = 1;

    public static void main(String[] args) {
        PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable();
        Thread f = new Thread(new First(sequence), "Fisrt");
        Thread s = new Thread(new Second(sequence), "Second");
        Thread t = new Thread(new Third(sequence), "Third");
        f.start();
        s.start();
        t.start();
    }
}

class First implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public First(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printFist();
    }

    private void printFist() {
        synchronized (sequence) {
            for (int i = 1; i <= 20; i += 3) {
                while (sequence.notifyValue != 1) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 2;
                sequence.notifyAll();
            }
        }
    }
}

class Second implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Second(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printSecond();
    }

    private void printSecond() {
        synchronized (sequence) {
            for (int i = 2; i <= 20; i += 3) {
                while (sequence.notifyValue != 2) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 3;
                sequence.notifyAll();
            }
        }
    }

}

class Third implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Third(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printThrid();
    }

    private void printThrid() {
        synchronized (sequence) {
            for (int i = 3; i <= 20; i += 3) {
                while (sequence.notifyValue != 3) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 1;
                sequence.notifyAll();
            }
        }
    }
}

您需要在每个线程上对值进行排序。每次线程写入一个数字时,它都会触发事件总线中的一个事件。所有线程都订阅了该事件。

您通过触发事件 [最小值 - 1] 来启动系统。

每个线程都会收到一个通知,告知已发布值 [最小值 - 1]。只有具有值 [最小值] 的线程才会动作,并会触发值为 [最小值 + 1] 的新事件。

编辑:我还没有测试过,但类似这样。

static void main(String[] args) {
    List<Deque<Integer>> publishQueues = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        new Thread(new Worker(i, publishQueues)).start();
    }
}

class Worker implements Runnable {
    Deque subscriberQueue;
    List<Deque<Integer>> publishQueues;
    int i;
    Worker(int i, List<Deque<Integer>> publishQueues) {
        this.i = i;
        this.publishQueues = publishQueues;
        this.subscriberQueue = new ConcurrentLinkedDeque<>();
        this.publishQueues.add(this.subscriberQueue);
    }

    void Run() {
        LinkedList<Integer> ints = new LinkedList<>();
        for (int j = i; j <= 100; j+=10) {
            ints.add(j);
        }

        while (true) {
            Integer publishedInteger = subscriberQueue.poll();
            if (publishedInteger == ints.getFirst() - 1) {
                Integer integer = ints.poll();
                System.out.println(integer);
                for (Dequeu<Integer> publishQueue : publishQueues) {
                    publishQueue.addLast(integer);
                }
            }
        }
    }
}