Многопоточность в Java. Очередность выполнения потоков
Буду очень благодарен за подсказку, как правильно вывести на печать результаты решения задания с потоками на языке Java . При выводе на печать результаты по некоторым потокам "налезают" друг на друга. Нужно сделать так, чтобы потоки выполнялись и выводились на печать не пересекаясь, один после другого, в заданной очередности. Т.е. при выводе на печать в консоли должно быть следующее:
Создать класс, реализующий интерфейс Runnable. Реализовано на примере создания счётчика от 1-го до 5-ти: Runnable count 1 Runnable count 2 Runnable count 3 Runnable count 4 Runnable count 5
Переопределить run() метод. Создать цикл for. В цикле распечатать значения от 0 до 100 делящиеся на 10 без остатка: 0 10 20 30 40 50 60 70 80 90 100
Использовать статический метод Thread.sleep(), чтобы сделать паузу. Реализовано путём создания паузы 1500 миллисекунд между выводом на печать значений счетчика '1' и '2': Counter value: 1 Counter value: 2
Создать три потока, выполняющих задачу распечатки значений. Реализовано на примере вывода уведомлений о старте и финише трёх потоков: Thread1 started Thread2 started Thread3 started Thread1 finished Thread2 finished Thread3 finished
Спасибо. Вот мой код:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
static final List<String> strings = Collections.synchronizedList(new ArrayList<>());
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service1 = Executors.newFixedThreadPool(1);
Thread t1 = new Thread(new MyThread1());
t1.start();
service1.shutdown();
ExecutorService service2 = Executors.newFixedThreadPool(1);
Thread t2 = new Thread(new MyThread2());
t2.start();
service2.shutdown();
ExecutorService service3 = Executors.newFixedThreadPool(1);
Thread t3 = new Thread(new MyThread3());
t3.start();
service3.shutdown();
ExecutorService service4 = Executors.newFixedThreadPool(1);
Thread t4 = new Thread(new MyThread4());
t4.start();
service4.shutdown();
}
static class MyThread1 implements Runnable {
@Override
public void run() {
synchronized (strings) {
System.out.println("1. Создать класс, реализующий интерфейс Runnable." +
"\nРеализовано на примере создания счётчика от 1-го до 5-ти:");
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Runnable count " + (i + 1));
}
System.out.println();
}
}
}
static class MyThread2 implements Runnable {
@Override
public void run() {
synchronized (strings) {
System.out.println("2. Переопределить run() метод. Создать цикл for. В цикле распечатать значения " +
"\nот 0 до 100 делящиеся на 10 без остатка:");
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i % 10 == 0) {
System.out.println(i);
}
}
System.out.println();
}
}
}
static class MyThread3 implements Runnable {
@Override
public void run() {
synchronized (strings) {
System.out.println("3. Использовать статический метод Thread.sleep(), чтобы сделать паузу." +
"\nРеализовано путём создания паузы 1500 миллисекунд между выводом на печать " +
"\nзначений счетчика '1' и '2':");
for (int i = 0; i < 2; i++) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Counter value: " + (i + 1));
}
System.out.println();
}
}
}
static class MyThread4 implements Runnable {
@Override
public void run() {
synchronized (strings) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4. Создать три потока, выполняющих задачу распечатки значений." +
"\nРеализовано на примере вывода уведомлений о старте и финише трёх потоков:");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 3; i++) {
System.out.println("Thread" + (i + 1) + " started");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 3; i++) {
System.out.println("Thread" + (i + 1) + " finished");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.exit(0);
}
}
}
Ответы (1 шт):
При одновременном запуске нескольких потоков невозможно предсказать их очередность выполнения. Чтобы потоки выполнялись в заданном порядке можно использовать .join():
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyThread1());
t1.start();
t1.join ();
Thread t2 = new Thread(new MyThread2());
t2.start();
t2.join ();
Thread t3 = new Thread(new MyThread3());
t3.start();
t3.join ();
Thread t4 = new Thread(new MyThread4());
t4.start();
t4.join ();
}