WedX - журнал о программировании и компьютерных науках

Как вручную контролировать, какой поток входит в критическую область с помощью Java Swing?

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

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

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

Я создал класс "Incrementor", который увеличивает значение int, но если я попытаюсь добавить ключевое слово synchronized в метод 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();
            }
        }
    }

Любые советы о том, как действовать?

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


  • См. java.util.concurrent.Semaphore и друзей. 25.04.2019

Ответы:


1

ваша проблема - ужасная блокировка потока !!

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

конечно ! Диспетчер потоков изменяет «Рабочий» поток всякий раз, когда ему это нравится!, и вы должны опубликовать здесь больше кода, но на первый взгляд вы используете один и тот же метод в обоих потоках, поэтому он будет сброшен до 2 случая: -

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

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

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

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

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

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

генерирует исключение IllegalThreadStateException, если поток уже запущен.

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

25.04.2019

2

Вы можете использовать блокировку на уровне объекта, используя ключевое слово 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;
    }
}

or

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;
      }
    }
}
25.04.2019
Новые материалы

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


Для любых предложений по сайту: [email protected]