есть код
class SomeThread extends Thread {
public void run() {
for (int i=0; i < 10; i++)
System.out.println(i);
}
}
public class Main {
public static void main(String[] args) {
SomeThread test = new SomeThread();
test.start();
SomeThread test2 = new SomeThread();
test2.start();
}
}
в теории должны били вывестись числа от 0 до 9 потоком. Но они выводятся по очереди, с начала первые 10 чисел от 0 до 9, затем следующее 10 чисел от 0 до 9. Подскажите в чём проблема ?
Причина в неодновременном запуске потоков. Используйте для их синхронного запуска CountDownLatch:
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
class SomeThread extends Thread {
public void run() {
try {
countDownLatch.await();
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
} catch (InterruptedException ex) {
Logger.getLogger(TestString.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class Main {
public static void main(String[] args) {
SomeThread test = new SomeThread();
test.start();
SomeThread test2 = new SomeThread();
test2.start();
countDownLatch.countDown();
}
}
Тут нет проблемы. Просто нужно осознавать, что создание потока требует некоторых накладных расходов по времени. В итоге получается ситуация, что Вы создали первый поток, запустили его и только потом создаете второй поток. В итоге, когда второй поток создался и Вы запускаете его - первый уже отработал.
Это легко проверить путем увеличения цикла (попробуйте 100, 1000 и тд).
Вариант решения проблемы - сперва создать 2 потока, потом их запустить.
Советую тебе изучить жц потоков.Запуск потока не дает никакую гарантию на то что поток будет работать.У джава есть обработчик потоков он сам определяет какой поток будет выполнятся так же он сам определят когда остановить поток поэтому советую тебе 100 раз перезапустить программу и при запуске программа по разному будет себя вести
class SomeThread implements Runnable {
Thread thrd;
SomeThread(String name){
thrd = new Thread(this, name);
thrd.start();
}
public void run() {
for (int i=0; i < 10; i++) {
System.out.println(i + thrd.getName());
try{
Thread.sleep(1000);
} catch (InterruptedException exc) {
System.out.println("Exception in added thread : " + exc);
}
}
System.out.println("End thread : " + thrd.getName());
}
}
class Test {
public static void main(String[] args) {
SomeThread test1 = new SomeThread("test1");
SomeThread test2 = new SomeThread("test2");
try {
Thread.sleep(10000);
test1.thrd.join();
test2.thrd.join();
} catch(InterruptedException exc) {
System.out.println("Exception in main thread : " + exc);
}
}
}
Пару моментов:
run(), хорошим тоном является расширение интерфейса Runnable, в котором объявлен, лишь метод run(). Ни в чем. У тебя 3 потока: test, test2 и main. main запускает test и идет дальше к test2.start(). Если нужно поочередно, вставь следующее после test.start()
test.join();
public class SomeThread extends Thread {
@Override
public void run() {
for (int i=0; i < 10; i++) {
System.out.println(i);
}
}
public static void main(String[] args) throws InterruptedException {
SomeThread test = new SomeThread();
test.start();
test.join();
SomeThread test2 = new SomeThread();
test2.start();
}
}
Может дело в том что у println есть так же своя внутренняя синхронизация, и его просто захватывает потом в цикле и не отпускает до окончания цикла. Плюс к тому, код может выполняется быстрее чем приходит прерывание и выкидывает его из ядра.
public void println(int x) {
synchronized (this) {
print(x);
newLine();
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости