序号使用线程同步
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);
}
}
}
}
}
我想使用 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);
}
}
}
}
}