Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.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_Singleton_Synchronized - Fatal编程技术网

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

Java等待/通知不在线程中调用,java,multithreading,singleton,synchronized,Java,Multithreading,Singleton,Synchronized,我在调度两个线程ReadData和WriteData时遇到问题。看来等了以后我不能通知你了。 下面是我定义并调用的类: 缓冲区:我用来读/写数据的缓冲区。我同步这个类 公共类缓冲区{ //用于存储数据的缓冲区大小 公共静态最终整数大小=10; //缓冲区的数据。 私有int[]值; //数据中元素的计数。 私人整数计数; //缓冲区实例,用于单例模式 私有静态缓冲区实例=null; //显示正在使用的数据忙或不忙的信号 私有静态对象互斥=新对象; //缓冲区构造函数 专用缓冲区{ 值=新整数[大

我在调度两个线程ReadData和WriteData时遇到问题。看来等了以后我不能通知你了。 下面是我定义并调用的类:

缓冲区:我用来读/写数据的缓冲区。我同步这个类

公共类缓冲区{ //用于存储数据的缓冲区大小 公共静态最终整数大小=10; //缓冲区的数据。 私有int[]值; //数据中元素的计数。 私人整数计数; //缓冲区实例,用于单例模式 私有静态缓冲区实例=null; //显示正在使用的数据忙或不忙的信号 私有静态对象互斥=新对象; //缓冲区构造函数 专用缓冲区{ 值=新整数[大小]; 计数=0; } //获取缓冲区的实例。 公共静态缓冲区实例{ iInstance==null{ 同步互斥{ iInstance==null实例=新缓冲区; } } 返回实例; } public void addValueint值{ 同步互斥{ ifcount>=大小返回; 数值[计数++]=数值; } } //返回当前数据,然后重置缓冲区。 公共int[]获取值{ 同步互斥{ ifcount==0返回null; int[]值=新的int[count]; System.arraycopythis.values,0,values,0,count; 计数=0; 返回值; } } 公共整数getCount{ 同步互斥{ 返回计数; } } } ReadData:我使用这个类将数据存储到缓冲区中

导入java.util.Random; 公共类ReadData实现可运行{ Buffer Buffer=Buffer.getInstance; @凌驾 公共同步无效运行{ 随机=新随机; whiletrue{ ifbuffer.getCount>=Buffer.SIZE{ 试一试{ System.out.printlnRead:正在等待。; mState.readIsWaiting; 等待 }捕捉中断异常e{ e、 打印跟踪; } }否则{ System.out.printlnRead:存储数据; buffer.addValuerandom.nextinBuffer.SIZE+1; } } } 公共接口读取状态{ 无效阅读等待; } 私有只读状态mState; public void setreadstate读取状态{ mState=状态; } 公共同步的void makeNotify{ 通知所有人; } } WriteData:我用来从缓冲区获取数据的类

公共类WriteData实现可运行{ Buffer Buffer=Buffer.getInstance; @凌驾 公共同步无效运行{ whiletrue{ ifbuffer.getCount==0{ 试一试{ System.out.printlwrite:正在等待。; mState.writeIsWaiting; 等待 }捕捉中断异常e{ e、 打印跟踪; } }否则{ int[]getdata=buffer.getValues; System.out.printlnfirst数据:+getdata[0]; } } } 公共界面不动产{ 等待无效; } 私人地产; 公共无效setWriteStateWriteState状态{ mState=状态; } 公共同步的void makeNotify{ 通知所有人; } } MyThread:我用来开始读/写的线程

主包装; 导入testing.ReadData; 导入测试.WriteData; 公共类MyThread实现ReadData.ReadState、WriteData.WriteState{ 私有读取数据读取; 私有写入数据写入; 公共无效启动{ 读取=新的读取数据; 写入=新写入的数据; read.setReadStatethis; write.setWriteStatethis; 新thread.start; 新建Threadwrite.start; } @凌驾 公共无效等待{ read.makeNotify; } @凌驾 公众阅读等待{ 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]);
            }
        }

    }

可能与您的问题无关,但BuffergetInstance方法不是完全线程安全的。请参见制作示例vola
瓷砖修复它感谢你的评论,但它仍然有相同的问题!我想这不是问题。你只需要交换读写。我认为问题在于日程安排。因为有时它工作,有时不工作。所以根据你的说法,如果缓冲区满了,读卡器可以阻止,如果缓冲区空了,写卡器可以阻止?你可能不明白我的意思。WriteData:我希望从缓冲区获取数据并将其存储在某个位置,而不仅仅是控制台,数据不仅仅是数组int,ReadData:我希望从任何源读取数据并将其存储到缓冲区。缓冲区是临时限制数据。