Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现线程等待通知?_Java_Multithreading - Fatal编程技术网

Java 如何实现线程等待通知?

Java 如何实现线程等待通知?,java,multithreading,Java,Multithreading,这是我写的代码。我试过很多方法,但都不管用。请帮助pause()方法工作,但continue()不工作 public abstract class Figure implements Runnable { public static final Color DEFAULT_COLOR = Color.ORANGE; public static final int DEFAULT_X = 30; public static final int DEFAULT_Y = 30

这是我写的代码。我试过很多方法,但都不管用。请帮助
pause()
方法工作,但
continue()
不工作

public abstract class Figure implements Runnable {

    public static final Color DEFAULT_COLOR = Color.ORANGE;
    public static final int DEFAULT_X = 30;
    public static final int DEFAULT_Y = 30;
    public static final int DEFAULT_WIDTH = 50;
    public static final int DEFAULT_HEIGHT = 50;
    /**
     *
     */
    private int x;
    private int y;
    private int width;
    private int height;
    private Color color;
    /**
     * speed per OX projection
     */
    private int xS;
    /**
     * speed per OY projection
     */
    private int yS;
    private Thread t;
    private boolean isRunning;
    private boolean isPaused;
    private FigureCanvas panel;

    // START CONSTRUCTORS
    // WE can add more constructor with other parameter group if it is necessary
    protected Figure() {
        this(DEFAULT_X, DEFAULT_Y, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_COLOR);

    }

    protected Figure(int x, int y, int width, int height) {
        this(x, y, width, height, DEFAULT_COLOR);
    }

    protected Figure(int x, int y, int width, int height, Color color) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.color = color;


    }
// END OF CONSTRUCTORS

    //Start getters and setters block
    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        if (width < 0) {
            System.out.println("Incorrect parameter error: width can not be negative ");
            return;
        }
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        if (height < 0) {
            System.out.println("Incorrect parameter error: height can not be negative ");
            return;
        }
        this.height = height;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
//End of getters and setters block

    public abstract boolean isBelong(int x, int y);

    public abstract void draw(Graphics g);

    @Override
    public void run() {
        System.out.println("In RUN method");
        while (isRunning) {
            System.out.println("running");
        }
    }

    public void move(int xS, int yS) {
        x += xS;
        y += yS;
    }

    public void move() {
        xS = 1;
        yS = 1;
        move(xS, yS);
    }

    public void stop() {
        // TODO stop thread
    }

    public void continueRun() {
//      ToDO notify
        synchronized (t) {
            isRunning = true;

            t.notify();
        }
    }

    public void pause() {
        // TODO organize wait
        synchronized (t) {
            try {
                isRunning = false;
                t.wait();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void start() {
//  TODO    start new thread and callits start method
        t = new Thread(this);
        isRunning = true;
        t.start();
    }

    @Override
    public String toString() {
        return "Figure{"
                + "x=" + x
                + ", y=" + y
                + ", width=" + width
                + ", height=" + height
                + ", color=" + color
                + '}';
    }
}
public抽象类Figure实现Runnable{
公共静态最终颜色默认值_Color=Color.ORANGE;
公共静态最终整数默认值_X=30;
公共静态最终整数默认值_Y=30;
公共静态最终整数默认值_宽度=50;
公共静态最终int默认值_高度=50;
/**
*
*/
私人INTX;
私营企业;
私有整数宽度;
私人内部高度;
私人色彩;
/**
*每牛投影速度
*/
私有int-xS;
/**
*每瓦速度投影
*/
私营企业;
私有线程t;
私有布尔运算;
私用布尔值;
私人图形CAVAS面板;
//启动构造函数
//如果有必要,我们可以添加更多的构造函数和其他参数组
受保护图形(){
这(默认X、默认Y、默认宽度、默认高度、默认颜色);
}
受保护图形(整数x、整数y、整数宽度、整数高度){
这(x、y、宽度、高度、默认颜色);
}
受保护图形(整数x、整数y、整数宽度、整数高度、颜色){
这个.x=x;
这个。y=y;
这个。宽度=宽度;
高度=高度;
这个颜色=颜色;
}
//构造函数结束
//启动getter和setter块
公共int getX(){
返回x;
}
公共无效集合x(整数x){
这个.x=x;
}
公共int getY(){
返回y;
}
公共空间设置(整数y){
这个。y=y;
}
公共int getWidth(){
返回宽度;
}
公共void setWidth(int-width){
如果(宽度<0){
System.out.println(“参数错误:宽度不能为负”);
返回;
}
这个。宽度=宽度;
}
公共整数getHeight(){
返回高度;
}
公共空间设置高度(内部高度){
如果(高度<0){
System.out.println(“参数错误:高度不能为负”);
返回;
}
高度=高度;
}
公共颜色getColor(){
返回颜色;
}
公共空间设置颜色(颜色){
这个颜色=颜色;
}
//getter和setter块的末尾
公共抽象布尔值(intx,inty);
公开摘要作废图(图g);
@凌驾
公开募捐{
System.out.println(“运行中方法”);
同时(正在运行){
System.out.println(“运行”);
}
}
公共无效移动(int xS,int yS){
x+=xS;
y+=yS;
}
公开作废动议(){
xS=1;
yS=1;
移动(xS,yS);
}
公共停车场(){
//TODO停止线程
}
公共无效连续体(){
//待办事项通知
同步(t){
isRunning=true;
t、 通知();
}
}
公共空间暂停(){
//待办事项组织等待
同步(t){
试一试{
isRunning=false;
t、 等待();
}捕获(中断异常例外){
例如printStackTrace();
}
}
}
公开作废开始(){
//TODO start新线程和CALITS start方法
t=新螺纹(本螺纹);
isRunning=true;
t、 start();
}
@凌驾
公共字符串toString(){
返回“图{”
+“x=”+x
+“,y=“+y
+“,width=“+width
+“,height=“+height
+”,color=“+color
+ '}';
}
}

您正在等待对象
t
,因此要醒来,您还需要对象
t
的通知

如果您试图执行类似的操作,您不应该忘记,在这种情况下,notify是在b对象中执行的。

我一直在使用a来表示“pausable runnables”,我发现它更容易维护。以下是我使用的模式:

public class Q22569411 implements Runnable {

private volatile boolean paused;
private volatile boolean stop;
private final Semaphore pauseLock = new Semaphore(0);

@Override
public void run() {

    while (!stop) {
        work();
        if (paused) {
            System.out.println("Pausing work.");
            try { 
                pauseLock.acquire();
            } catch (InterruptedException ie) {
                System.out.println("Pause interrupted.");
            }
        }
    }
    System.out.println("Stopped running");
}

protected void work() {

    System.out.println("Working");
    try {
        Thread.sleep(100);
    } catch (InterruptedException ie) {
        System.out.println("Work interrupted.");
    }
}

public boolean isPaused() {
    return paused;
}

public void setPaused(boolean pause) {

    if (this.paused == pause) {
        return;
    }
    if (this.paused) {
        paused = false;
        pauseLock.release();
    } else {
        // Remove previous release in case this method is called repeatedly
        pauseLock.tryAcquire();
        paused = true;
    }
}

public void stopRunning() {

    stop = true;
    pauseLock.release();
}

}

因为
continueRun()
通知
这个
对象,而
pause()
方法也在等待
t
上的信号,run()方法在不同步的情况下读取isRunning标志,我真的不明白pause()在等待什么:它在被唤醒后什么也不做。和wait()应该总是在循环中调用,正如文档所解释的那样。@JBNizet right,
isRunning
标志也应该是可变的。pause()方法必须等待线程,然后在调用continue()时,它必须唤醒并继续工作