繁体   English   中英

Java等待/通知未在线程中调用

[英]Java wait/notify not call in thread

调度两个线程( ReadDataWriteData )时出现问题。 看来我等不及通知。 这是我定义和调用的班级:

缓冲区:我用来读取/写入数据的缓冲区。 我同步这堂课。

public class Buffer {
    // Size of buffer we use to store data
    public static final int SIZE = 10;

    // Data of buffer.
    private int[] values;

    // Count of element in data.
    private int count;

    // Instance of buffer, for singleton pattern 
    private static Buffer instance = null;

    // A signal show data in use (busy) or not
    private static Object mutex = new Object();

    // Constructor of buffer
    private Buffer(){
        values = new int[SIZE];
        count = 0;
    }

    // Get instance of buffer.
        public static  Buffer getInstance(){
            if(instance == null){
                synchronized (mutex) {
                    if(instance == null) instance = new Buffer();
                }           
            }
            return instance;
        }


        public void addValue(int value){
            synchronized (mutex) {
                if(count >= SIZE) return;

                values[count++] = value;
            }
        }

        // Return current data and then reset buffer.
        public int[] getValues(){
            synchronized (mutex) {
                if(count == 0) return null;

                int[] values = new int[count];
                System.arraycopy(this.values, 0, values, 0, count);
                count = 0;
                return values;
            }
        }

        public int getCount(){
            synchronized (mutex) {
                return count;
            }
        }
}

ReadData:我用于将数据存储到缓冲区的此类。

import java.util.Random;

public class ReadData implements Runnable {
    Buffer buffer = Buffer.getInstance();

    @Override
    public synchronized void run() {
        Random random = new Random();
        while(true){
            if(buffer.getCount() >= Buffer.SIZE){
                try {
                    System.out.println("Read: is waiting. . .");
                    mState.readIsWaiting();
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Read: storing data");
                buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
            }
        }

    }

    public interface ReadState{
        void readIsWaiting();
    }

    private ReadState mState;

    public void setReadState(ReadState state){
        mState = state;
    }

    public synchronized void makeNotify() {
        notifyAll();        
    }

}

WriteData:我用来从缓冲区中获取数据的此类

 public class WriteData implements Runnable {
        Buffer buffer = Buffer.getInstance();

        @Override
        public synchronized void run() {
            while(true){
                if(buffer.getCount() == 0){
                    try {
                        System.out.println("Write: is waiting. . .");
                        mState.writeIsWaiting();
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    int[] getdata = buffer.getValues();
                    System.out.println("first data: " + getdata[0]);
                }
            }

        }

        public interface WriteState{
            void writeIsWaiting();
        }

        private WriteState mState;

        public void setWriteState(WriteState state){
            mState = state;
        }

        public synchronized void makeNotify() {
            notifyAll();        
        }
    }

MyThread:我用来开始读/写的线程

package main;

import testing.ReadData;
import testing.WriteData;


public class MyThread implements ReadData.ReadState, WriteData.WriteState  {
    private ReadData read;
    private WriteData write;

    public void start(){
        read = new ReadData();
        write = new WriteData();
        read.setReadState(this);
        write.setWriteState(this);
        new Thread(read).start();
        new Thread(write).start();
    }

    @Override
    public void writeIsWaiting() {
        read.makeNotify();

    }

    @Override
    public void readIsWaiting() {
        write.makeNotify();

    }

}

而已。 有时它会起作用,很多时候它会停止并等待。 我该如何解决这个问题? 谢谢

我认为您已经用WriteData颠倒了ReadData实现。 在显示的代码中,如果缓冲区已满,ReadData线程将阻塞:

@Override
public synchronized void run() {
    Random random = new Random();
    while(true){
        if(buffer.getCount() >= Buffer.SIZE){
            try {
                System.out.println("Read: is waiting. . .");
                mState.readIsWaiting();
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Read: storing data");
            buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
        }
    }

}

您真正需要的是:

@Override
public synchronized void run() {
    Random random = new Random();
    while(true){
        if(buffer.getCount() == 0){
            try {
                System.out.println("Read: is waiting. . .");
                mState.readIsWaiting();
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Read: storing data");
            buffer.addValue(random.nextInt(Buffer.SIZE) + 1);
        }
    }

}

同样,在WriteData实现中,如果缓冲区已满,则应阻塞。 如果读者没有机会从缓冲区中取出元素,则会发生这种情况。 这应该适用于WriteData代码:

    @Override
    public synchronized void run() {
        while(true){
            if(buffer.getCount() >= Buffer.SIZE){
                try {
                    System.out.println("Write: is waiting. . .");
                    mState.writeIsWaiting();
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                int[] getdata = buffer.getValues();
                System.out.println("first data: " + getdata[0]);
            }
        }

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM