【问题标题】:Java synchronization using .wait(millis)使用 .wait(millis) 进行 Java 同步
【发布时间】:2017-05-03 18:24:18
【问题描述】:

我有一个关于同步的“小问题”,这是我的场景(我对同步的了解还不够,我还在学习): (编辑)

        Thread work, progress;
        final Object myObject;
        work = new Thread(() -> {
            try {
                myObject.doSomething();
            } catch (IOException e) {e.printStackTrace();}
        });

        progress = new Thread(() -> {
            while (true) {
                System.out.println(myObject.progress());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });

        work.setDaemon(true);
        progress.setDaemon(true);

        work.start();
        progress.start();

        work.join();
        progress.interrupt();
        progress.join();

        /*Other code*/

(编辑:可能已解决)

主作业在WORK线程中完成,作业进度在PROGRESS线程中打印;

这很好用,但我想要一个更好的……“同步”: 唯一的“小”问题是,如果我在 sleep 方法中放了 1 小时,也许工作已经完成,必须等待这 55 分钟才能终止 PROGRESS 线程...... 如何处理这种情况?我希望我的 PROGRESS 线程在工作完成时终止,而不是等待睡眠方法完成。 我想我将不得不使用一些同步块,以及一个 .wait(millis) 调用而不是那个 .sleep(millis) ... 有人可以帮我理解吗?谢谢!

【问题讨论】:

  • 如果目标是更新进度系统,您可以考虑将进度更新器传递给工作对象(通过接口),然后让工作人员在进度监视器上调用更新。它是例如 Eclipse 实现进度更新的方式。
  • 查看wait/notify/notifyAll,或者java.util.concurrent(和子包)中更高级的功能。
  • 您也可以在工作线程完成时(即在 join() 返回后)简单地中断进度线程。不需要线程不安全的done 数组。 docs.oracle.com/javase/tutorial/essential/concurrency/…
  • @MarkRotteveel 我尝试使用带有 .wait(millis) 的等待/通知系统,以便 PROGRESS 线程立即终止,但它没有工作:程序只是进入它遇到的第一个同步块, 没有别的(如果首先达到 WORK 线程同步块,那么我不会从 PROGRESS 中得到任何打印,反之亦然,我只能得到进度的打印,但没有工作)......
  • @JBNizet 我知道,我正在使用该布尔数组来实现等待/通知系统,并使用该值来防止虚假唤醒。

标签: java multithreading synchronization wait


【解决方案1】:

也许您可能想研究观察者/监听者模式。简单地说,你的观察者在它订阅的类通知它之前什么都不做。

http://www.javaworld.com/article/2077258/learn-java/observer-and-observable.html

// Your observable class
import java.util.Observable;
public class ObservableValue extends Observable
{
    private int n = 0;
    public ObservableValue(int n)
    {
        this.n = n;
    }
    public void setValue(int n)
    {
        this.n = n;
        setChanged();
        notifyObservers();
    }
    public int getValue()
    {
        return n;
    }
}


// Your observer
import java.util.Observer;
import java.util.Observable;
public class TextObserver implements Observer {
    private ObservableValue ov = null;
    public TextObserver(ObservableValue ov) {
        this.ov = ov;
    }
    public void update(Observable obs, Object obj) {
        if (obs == ov) {
            System.out.println(ov.getValue());
        }
    }
}


public class Main {
    public Main() {
        ObservableValue ov = new ObservableValue(0);
        TextObserver to = new TextObserver(ov);
        ov.addObserver(to);
    }
    public static void main(String [] args) {
        Main m = new Main();
    }
}

可以在此处找到将观察者模式与多线程一起使用的示例: https://dzone.com/articles/the-observer-pattern-using-modern-java

解决这个问题的一个有趣方法是使用响应式原则。在这个视频中可以看到一个快速的演示和解释: https://www.youtube.com/watch?v=weWSYIUdX6c

【讨论】:

  • 感谢您的回答!我想我解决了主要问题,但无论如何我都会看看这些链接!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
相关资源
最近更新 更多