Как вручную контролировать, какой поток входит в критическую область, используя Java Swing? - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь создать простое приложение на основе Java Swing, которое вручную управляет двумя потоками, которые пытаются непрерывно увеличивать целочисленное значение. Приложение должно иметь возможность 'Start' и 'Stop' любого из потоков (оба потока увеличивают значение одновременно) и помещать любой из потоков в критическую область (только один поток может увеличивать значение).

Вот скриншот того, что у меня есть, чтобы вы могли лучше понять, к чему я стремлюсь:

https://i.imgur.com/sQueUD7.png

Я создал класс «Incrementor», который выполняет работу по увеличению значения int, но если я пытаюсь добавить синхронизированное ключевое слово в метод increment (), я не получаю желаемый результат.

    private void increment() {
        while (Thread.currentThread().isAlive()) {
            if (Thread.currentThread().getName().equals("Thread 1")) {
                if (t1Stop.isEnabled()) {
                    value++;
                    t1TextField.setText("Thread 1 has incremented value by 1. Current value = " + value + "\n");
                }
            } else if (Thread.currentThread().getName().equals("Thread 2")) {
                if (t2Stop.isEnabled()) {
                    value++;
                    t2TextField.setText("Thread 2 has incremented value by 1. Current value = " + value + "\n");
                }
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

Любой совет, как поступить?

Надеюсь, я дал понять, что именно я ищу, если нет, дайте мне знать, и я обновлю этот пост.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Ваша проблема в страшной блокировке потока !!

, но если я попытаюсь добавить синхронизированное ключевое слово в метод increment (), я не получу желаемый результат.

конечно!Диспетчер потоков изменяет «рабочий» поток всякий раз, когда ему это кажется!

  1. хороший случай!Диспетчер потоков изменяет поток после того, как он завершает вызов метода приращения (старый добрый выигрыш win для обоих потоков ^ - ^).
  2. плохой случай (и это то, с чем вы столкнулись) представьте, что поток получил доступ кметод, и перед завершением метода менеджеры потоков изменяют его, и когда другой метод пытается получить к нему доступ, обнаруживает большой неприятный synchronized в его лице с блокировкой в ​​другом потоке! отсюда их нет никакой гарантии, что произойдет, но яможет заверить вас, что 90% результатов этого случая только радует менеджер потоков.

Приложение должно иметь возможность «Пуск» и «Стоп» любого из потоков (оба потока увеличиваютзначение одновременно) и поместите любой из потоков в критическую область (только одному потоку разрешено увеличивать значение).

извините, что сломал его вам, но диспетчер потоков не контролируется моим другом.но мы можем предложить достаточное количество вещей для менеджера потоков, поэтому то, чего вы пытаетесь достичь, невозможно в менеджере потоков Java.

и остановка потока, да, но запуск потока после его остановкибольшое НЕТ !!!

из документации Thread.start()

Никогда не разрешается запускать поток более одного раза.В частности, поток не может быть перезапущен после завершения выполнения.

создает исключение IllegalThreadStateException, если поток уже был запущен.

вот очень полезная ссылка, по которой можно получить темуобъяснил более широко у оракула

0 голосов
/ 25 апреля 2019

Вы можете использовать блокировку на уровне объекта, используя ключевое слово synchronized.

=> Блокировка на уровне объекта : To synchronize a non static method or block so that it can be accessed by only one thread at a time for that instance. It is used to protect non static data.

Пример:

public class ClasswithCriticalSections {
    private AtomicInteger count = new AtomicInteger(0);
    public synchronized int increment() {
      count.incrementAndGet();
      return count;
    }
}

или

public class ClasswithCriticalSections {
    Object lock1 = new Object();
    Object lock2 = new Object(); 
    private AtomicInteger count = new AtomicInteger(0);
    public int increment() {
      synchronized(lock1) {
         count.incrementAndGet();
         return count;
      }
    }
    public int decrement() {
      synchronized(lock2) {
         count.addAndGet(-1);
         return count;
      }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...