【问题标题】:How to manually control which Thread enters critical region using Java Swing?java - 如何使用Java Swing手动控制哪个线程进入临界区?
【发布时间】:2023-03-20 01:50:01
【问题描述】:

我正在尝试创建一个简单的基于 Java Swing 的应用程序,该应用程序手动控制两个线程,这两个线程都试图不断增加整数值。应用程序应该能够 'Start''Stop' 任一线程(两个线程同时递增值)并将任一线程置于临界区(只有一个线程允许增加值)。

这是我的截图,以便您更好地理解我的目标:

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和朋友们。

标签: java multithreading swing


【解决方案1】:

你的问题是可怕的线程锁!

但是如果我尝试将 synchronized 关键字添加到 increment() 方法中,我不会得到我想要的结果。

当然!线程管理器随时更改“工作”线程!,您应该在此处发布更多代码,但乍一看,您在两个线程中运行相同的方法,因此它将下降到 2 种情况:-

  1. 好案例! 线程管理器在完成调用增量方法后更改线程(两个线程都赢了 ^-^)。
  2. 糟糕的情况(这就是你所面临的) 想象一个线程访问了该方法,并且在完成该方法之前,线程管理器更改了它,当另一个方法尝试访问它时,发现它面对另一个线程中的锁是一个很大的讨厌 synchronized!从这里是他们不是保证会发生什么,但我可以向您保证,这种情况下 90% 的结果只会让线程管理器满意。

应用程序应该能够“启动”和“停止”任一线程(两个线程同时递增值)并将任一线程置于临界区(仅允许一个线程递增值)。

对不起,我的朋友,线程管理器是不可控制的。 但是我们可以向线程管理器提出相当多的建议,因此您尝试实现的目标在 java 线程管理器中是不可能的。

并且停止线程的 ooky dooky ,但是在停止线程后启动它是很大的 NO !!!

来自Thread.start() 文档

多次启动一个线程是不合法的。 特别是,线程一旦完成就可能不会重新启动 执行。

如果线程已经存在则抛出 IllegalThreadStateException 开始了。

这里有一个非常丰富的链接,您可以更广泛地解释该主题at the oracle's

【讨论】:

    【解决方案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;
        }
    }
    

    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;
          }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      相关资源
      最近更新 更多