This is a bounded buffer problem. There are suppose to be two threads, in and out. The in thread reads and existing file and puts the content into the buffer. The out thread reads from the buffer and writes to a new file. Simple concept but im getting some errors.

Here is my main class:

import java.io.*;
 
public class q2_main {
 
	public static void main(String[] args) throws FileNotFoundException {
		q2_buffer b= new q2_buffer(30);
 
		Thread r = new Thread(new q2_readerthread(b, "C:readin.txt"));
		Thread w = new Thread(new q2_writerthread(b, "C:output2.txt"));
 
		r.start();
		w.start();
 
		try {
			r.join();
			w.join();
		} catch (InterruptedException e) {
			System.out.println("ERROR WITH THREADS (ending program)");
			System.exit(0);
		}
	}
}

Here is my buffer class:

public class q2_buffer {
 
	private int in, out, size, items;
	//place for in and out, size of array, number of items in the array
	private char[] buffer;
 
	//constructor where s is the size of the buffer, also initializes variables
	public q2_buffer(int s) {
		size = s;
		buffer = new char[size];
		in = out = items = 0;
	}
 
	public int size(){
		return size;
	}
 
	public void add(char c) {
		while (items == size) { //if the buffer is full then wait
			try{
				wait();
			} catch (InterruptedException e) {
				System.out.println("ERROR ADDING CHAR TO BUFFER (ending program)");
				System.exit(0);
			}
		}
		notifyAll(); //needed to wake up waiting threads
		buffer[in] = c; //adds the char to the array/buffer
 
		in = (in + 1) % size; //move onto the next spot in the array, if at end, move back to the front
		items++; //increment number of items in array/buffer
 
	}
 
	public char removeItem() {
		while (items == 0) { //if there are no items in the buffer then wait
			try{
				wait();
			} catch (InterruptedException e) {
				System.out.println("ERROR REMOVING CHAR FROM BUFFER (ending program)");
				System.exit(0);
			}
		}
 
		notifyAll(); //needed to wake up waiting threads
		char c = buffer[out]; 
 
		out = (out + 1) % size; //move onto the next spot in the array, if at end, move back to the front
		items--; //decrement the number of items in the array/buffer
		return c; //this will be written to the file
	}
}

Here is my in/reader thread:

import java.io.*;
 
public class q2_readerthread implements Runnable{
 
	private q2_buffer buff;
	private String file;
 
	public q2_readerthread(q2_buffer b, String f) {
		buff = b;
		file = f;
	}
 
	public void run(){
		try{
			BufferedReader r = new BufferedReader(new FileReader(file));
			int current = r.read();
			char c;
 
			while(current != -1){
				c = (char) current;
				buff.add(c);
				try {
					wait(50); //wait 50ms after adding to the buffer
				} catch (InterruptedException e) {
					System.out.println("ERROR WAITING"); //should never get here
					System.exit(0);
				}
				current = r.read();
			}
			r.close(); //close file
		} catch(IOException e){
			e.printStackTrace();
			System.out.println("ERROR READING FILE (ending program");
			System.exit(0);
		}
	}
}

and lastly, here is my out/writer thread:

import java.io.*;
 
public class q2_writerthread implements Runnable{
 
	private q2_buffer buff;
	BufferedWriter w;
 
	public q2_writerthread(q2_buffer b, String f) {
		buff = b;
		try {
			w = new BufferedWriter(new FileWriter(f));
		} catch (IOException e) {
			System.out.println("ERROR WITH OUTPUT FILE LOCATION");
			System.exit(0);
		}
	}
 
	public void run() {
		while(buff.size() != 0){
			char c = buff.removeItem();
			try {
				w.write(c+"");
 
				try {
					wait(80); //wait 50ms after removing from the buffer
				} catch (InterruptedException e) {
					System.out.println("ERROR WAITING");
					System.exit(0);
				}
			} catch (IOException e1) {
				System.out.println("ERROR WRITING TO FILE");
				System.exit(0);
			}
		}
	}
}

Right now, these are the errors I am getting and I have no clue how to fix them:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Assignment3.q2_buffer.add(q2_buffer.java:29)
at Assignment3.q2_readerthread.run(q2_readerthread.ja va:23)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at Assignment3.q2_buffer.removeItem(q2_buffer.java:40 )
at Assignment3.q2_writerthread.run(q2_writerthread.ja va:22)
at java.lang.Thread.run(Unknown Source)

--------------

I am stuck, please help guys