Синхронизированное ключевое слово и условия гонки вызвали неожиданную ошибку в Java - PullRequest
0 голосов
/ 03 мая 2019

Я только начинаю основы работы с потоками в java. Синхронизированное ключевое слово говорит планировщику не переключать контекст во время выполнения потока.Кроме того, состояние гонки происходит, когда поток пытается получить доступ к одному и тому же ресурсу.Имея это в виду, я создал простой класс, чтобы продемонстрировать эту концепцию самому себе.

public class DemoThread{

    int i = 1;

    public void runThreads() {

        Thread t1 = new Thread(new Runnable () {
            @Override 
            public void run() {
                synchronized(this) {
                    i++;
                    System.out.println("Thread 1: " + i);
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(this) {
                    i--;
                    System.out.println("Thread 2: " + i);
                }
            }
        });

        for (int k = 0; k <=100; k++) {
            t1.start();
            t2.start();
        }
    }
}

У меня просто внизу forloop для выполнения этих потоков 100 раз.Тем не менее, я получаю эту ошибку в консоли:

Thread 2: 1Exception in thread "main" 
Thread 1: 1
java.lang.IllegalThreadStateException
    at java.base/java.lang.Thread.start(Thread.java:795)
    at thread_demo.DemoThread.runThreads(DemoThread.java:31)
    at thread_demo.main.main(main.java:9)

Почему это?

Ответы [ 3 ]

2 голосов
/ 03 мая 2019

Этот код:

        for (int k = 0; k <=100; k++) {
            t1.start();
            t2.start();
        }

запускается t1 и t2 более одного раза.Это запрещено.

2 голосов
/ 03 мая 2019

Метод start() в классе Thread имеет следующие строки:

 if (threadStatus != 0)
            throw new IllegalThreadStateException();

threadStatus используется для сигнализации состояния данного Thread.Если это 0, это означает, что Thread еще не запущен.Приведенный выше код означает, что, если Вы попытаетесь вызвать start() на Thread, который уже запущен - будет выдан IllegalThreadStateException.

Произошла конкретная ошибка, потому что Вы звоните start()метод более одного раза для данных потоков как t1, так и t2

1 голос
/ 03 мая 2019

Вы не можете запустить один и тот же поток несколько раз.
Пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...