Java 呼叫';等等';和';通知';关于这个

Java 呼叫';等等';和';通知';关于这个,java,multithreading,Java,Multithreading,在这里,我已经讨论了几乎所有关于java多线程的问题,但我不太明白我的理解是否正确 我希望了解操作顺序是否如下文所述 import javax.swing.*; import java.awt.FlowLayout; import java.awt.event.*; class Runner implements Runnable{ long count = 0; JLabel label; boolean paused = false; public Run

在这里,我已经讨论了几乎所有关于java多线程的问题,但我不太明白我的理解是否正确

我希望了解操作顺序是否如下文所述

import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;

class Runner implements Runnable{
    long count = 0;
    JLabel label;
    boolean paused = false;

    public Runner(JLabel label){
        this.label = label;
    }

    public void run(){
        while(true){
            try {
                if(paused){
                    synchronized(this){
                        wait();
                    }
                }
            } catch(InterruptedException e) {}
                count++;
                label.setText(Long.toString(count));
                if(Thread.interrupted())
                    return;
        }
    }

    synchronized void pause_counting(){
        paused = true;
    }

    synchronized void start_counting(){
        paused = false;
        notifyAll();
    }
}

public class ThreadRace extends JApplet{
    boolean running = true;
    Thread thread;

    @Override
    public void init(){
        final JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JLabel threadProgress = new JLabel("0");
        final Runner runner = new Runner(threadProgress);
        thread = new Thread(runner);
        thread.start();

        panel.add(threadProgress);

        JButton toggle = new JButton("Stop");
        toggle.addActionListener(new ActionListener() {
            @Override
            synchronized public void actionPerformed(ActionEvent e) {
                System.out.println("Running: " + running);
                if(running){
                    runner.pause_counting();
                } else {
                    runner.start_counting();    
                }
                running = !running;
            }
        });
        panel.add(toggle);

        add(panel);
    }

    public void stop(){
        thread.interrupt();
    }
}
这就是它的工作原理吗

  • 当我调用方法
    pause\u counting()
    时,我将paused设置为false
  • 在run()的内部,我持有对象的锁,
    runner
    synchronized(this){…}
    块的内部
  • 当我调用
    this.wait()
    时,我正在释放我刚刚拥有的同一个锁的锁,并进入
    WAITING
    状态
  • 此时,任何其他方法都可以自由地使用
    runner
    (!)
  • 我最终打电话给
    start\u counting()
  • 这使线程返回到
    运行状态,并在wait()语句之后继续。当它仍然在
    synchronized(this)
    块中时,它会获得锁
  • 但是,一旦离开块,它就会释放锁并继续执行
  • 我很确定我的理解有一些缺陷

    帮助?:(

    这就是它的工作原理吗

    是的。你所有的陈述都是正确的,只是做了一些调整(见下文)

    但是,您的程序中存在错误。因为线程正在测试
    paused
    ,而不是在
    synchronized
    块中,所以您需要确保
    paused
    volatile
    ,以提供内存同步

    volatile boolean paused = false
    
    对于
    JLabel
    数组,这可能也是必需的。每当有线程更改共享变量时,都需要进行内存同步

    volatile boolean paused = false
    

    当我调用pause_counting()方法时,我将pause设置为false

    是的。在这里更新
    暂停
    是可以的,因为它采用了
    同步
    方法

    在run()的内部,我持有一个对象的锁,即synchronized(this){…}块内部的runner[I]

    仅当
    paused
    为真时。由于您正在
    synchronized
    块外测试
    paused
    ,因此
    paused
    需要
    易失性
    ,以确保线程之间的内存同步

    当我调用this.wait()时,我正在释放对我刚刚拥有的同一个锁的持有,并进入等待状态

    在这一点上,任何其他方法都可以自由地使用这个runner[i](!)

    以前它可以自由地做一些事情,但是现在锁被释放了,它可以调用
    同步的
    方法而无需阻塞

    我最终打电话开始计算

    对。这将调用
    notifyAll()

    这会使线程返回到运行状态,并在wait()语句之后继续。当它仍在synchronized(This)块中时,它会获得锁

    首先,它会使线程进入
    BLOCKED
    状态,直到
    start\u counting()
    的调用方离开该方法并释放锁

    但是,一旦离开块,它就会释放锁并继续执行


    正确。

    不是答案,而是相关的(强烈推荐):您的第一个错误是在
    Runner
    的不同实例上同步。我知道理想情况下,这三个实例应该在同一个监视器上同步。但是,我明确希望了解使用
    替代此
    的效果。也许这不是最好的示例…
    是锁,但因为您是sy在3个不同的
    上运行此
    ,您将一事无成。我希望验证操作顺序是否如我所述。从实际需要多个锁的角度来看,代码本身是完全没有意义的,我也承认这一点。谢谢。:)在
    synchronized(此){…}
    块中包含对
    paused
    的检查将实现相同的目标,对吗?是的,这将在@SohamPal起作用。您还应该更新
    synchronized
    块中的
    JLabel
    ,或者将其设置为
    Runner
    上的
    volatile
    字段。