Dzień dobry,
Jestem w trakcie pisania implementacji kolejki cyklicznej, mam jednak kilka wątpliwości.
- Czy metody put() oraz take() działają poprawnie? Program zwraca np. coś takiego:
Odbieram element: 10 po raz: 1
Zamieszczam element: 10 po raz: 1
Zamieszczam element: 10 po raz: 2
Zamieszczam element: 10 po raz: 3
Zamieszczam element: 10 po raz: 4
Zamieszczam element: 10 po raz: 5
Odbieram element: 10 po raz: 2
Odbieram element: 10 po raz: 3
Odbieram element: 10 po raz: 4
Odbieram element: 10 po raz: 5
Exception in thread "main" java.lang.NullPointerException
at serialize.Circular.toString(Circular.java:311)
at serialize.CircularMain.main(CircularMain.java:56)
- W jaki sposób w metodzie toString uzyskać nazwę typu generycznego? Niestety, obecne rozwiązanie zwraca NullPointerException.
- Jak mogę uzyskać napis związany z obiektem?
Dziękuję za każdą pomoc.
package serialize;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.Iterator;
class Circular<E extends Serializable> implements Serializable, BlockingQueue<E> {
private final int size;
private int currentSize;
//private final BlockingQueue<E> delegate;
//private
private E[] buf;
private int front;
private int rear;
//private int lastElementIndex;
@SuppressWarnings("unchecked")
Circular(int size) {
this.size=size;
currentSize=0;
//@SuppressWarnings("unchecked")
buf = (E[])new Serializable[size];
front = 0;
rear = size-1;
}
@Override
public synchronized boolean add(E e) throws IllegalStateException, NullPointerException {
if(isFull()) {
throw new IllegalStateException("The buffer is full");
}
else if(e==null) {
throw new NullPointerException();
}
rear=incrementWithModulo(rear);
buf[rear]=e;
currentSize++;
return true;
}
@Override
public synchronized E remove() throws NoSuchElementException {
/*if(o==null) {
throw new NullPointerException();
}*/
if(isEmpty()) {
throw new NoSuchElementException("You cannot remove an element from empty buffer");
}
E element=buf[front];
buf[front]=null;
front=incrementWithModulo(front);
currentSize--;
return element;
}
@Override
public synchronized boolean isEmpty() {
return incrementWithModulo(rear)==front;
}
private int incrementWithModulo(int x) {
return (x+1)%size;
}
private boolean isFull() {
return incrementWithModulo(incrementWithModulo(rear))==front;
}
public synchronized E poll() {
if(isEmpty()) {
return null;
}
E element=buf[front];
buf[front]=null;
front=incrementWithModulo(front);
currentSize--;
return element;
}
public synchronized E take() throws InterruptedException {
E el=null;
try{
if(isEmpty()) {
monitor("wait");
}
el=poll();
monitor("notify"); //czy to jest w ogóle potrzebne?!
//return el;
}
catch(Exception ex) {
ex.printStackTrace();
}
return el;
}
@Override
public synchronized boolean offer(E e) {
if(isFull()) {
return false;
}
rear=incrementWithModulo(rear);
buf[rear]=e;
currentSize++;
return true;
}
@Override
public synchronized void put(E e) throws InterruptedException {
try{
if(isFull()) {
monitor("wait");
}
offer(e);
monitor("notify");
}
catch(Exception ex) {
ex.printStackTrace();
}
}
private synchronized void monitor(String intention) throws Exception {
if(intention.equals("wait")) {
wait();
}
else if(intention.equals("notify")) {
notifyAll();
}
}
@Override
public synchronized int size() {
//return (rear-front)+1;
return currentSize;
}
@Override
public synchronized boolean remove(Object o) {
try {
remove();
}
catch(NoSuchElementException e)
{
return false;
}
return true;
}
@Override
public synchronized E element() {
/*if(isEmpty()) {
return null;
}
return E;*/
return isEmpty() ? null : buf[front];
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) { //nadpisać!!!
//@SuppressWarnings("unchecked")
int size=size();
if(a.length<size) { //zbyt mała tablica wyjściowa
a=(T[])Array.newInstance(a.getClass().getComponentType(), size);
}
else if(a.length>size) {
}
int i=0;
for(E e : this) {
a[i]=(T)e;
++i;
}
//a=(T[])buf;
return a;
}
@Override
@SuppressWarnings("unchecked")
public E[] toArray() { //i to!!!
E[] array=(E[])Array.newInstance(buf.getClass().getComponentType(), size());
int i=0;
for(E e : this) {
array[i]=e;
++i;
}
return array;
}
@Override
public boolean containsAll(Collection<?> c) {
return false;
}
@Override
public boolean contains(Object o) {
return false;
}
@Override
public E peek() {
return buf[front];
}
@Override
public boolean removeAll(Collection<?> c) {
return false;
}
@Override
public int remainingCapacity() {
return -1;
}
@Override
public int drainTo(Collection<? super E> c) {
return -1;
}
@Override
public int drainTo(Collection<? super E> c, int maxElements) {
return -1;
}
@Override
public E poll(long timeout, TimeUnit unit) {
return poll();
}
@Override
public void clear() {
}
@Override
public boolean retainAll(Collection<?> c) {
return false;
}
@Override
public boolean addAll(Collection<? extends E> c) {
return false;
}
@Override
public boolean offer(E e, long timeout, TimeUnit unit) {
return false;
}
@Override
public Iterator<E> iterator() {
return new CircularIterator();
}
class CircularIterator implements Iterator<E> {
int current=front;
int last=rear;
public boolean hasNext() {
if(incrementWithModulo(current)!=front) {
return true;
}
else {
return false;
}
}
public E next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
int tempCurrent=current;
current=incrementWithModulo(current);
return buf[tempCurrent];
}
}
public String toString() {
E element=null;
String result="";
for(int i=0; i<size; ++i) {
int x=i-front<0 ? (size-i)-front : i-front;
//E element=(E)0;
//System.out.println(i+" "+(i-front)+" "+element.getClass().getSimpleName());
if(buf[i]==null) {
result+=i+" "+x+" "+element.getClass().getSimpleName()+" Empty";
}
else {
result+=i+" "+x+" "+element.getClass().getSimpleName()+" "+buf[i];
}
//Rozwiązanie nie jest idealne, ale może zadziała w konkretnym przypadku
}
return result;
}
}
package serialize;
import java.io.Serializable;
class CircularTest implements Runnable {
private Integer element;
private Integer secondElement;
private Circular<Integer> circular;
String name;
CircularTest(Circular<Integer> circular, String name) {
this.circular=circular;
this.name=name;
element=name.equals("Producer") ? 10 : 5;
}
void produce() throws InterruptedException {
circular.put(element);
}
void consume() throws InterruptedException {
secondElement=circular.take();
}
public void run() {
for(int i=1; i<6; ++i) {
try {
if(name.equals("Producer")) {
produce();
System.out.println("Zamieszczam element: "+element+" po raz: "+i);
}
else if(name.equals("Consumer")) {
consume();
System.out.println("Odbieram element: "+secondElement+" po raz: "+i);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package serialize;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class CircularMain {
public static void main(String[] args) {
Circular<Integer> circular=new Circular<>(10);
CircularTest prod=new CircularTest(circular, "Producer");
CircularTest kons=new CircularTest(circular, "Consumer");
Thread p=new Thread(prod);
Thread k=new Thread(kons);
p.start();
k.start();
try{
p.join();
k.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
Circular<Double> secondCircular=new Circular<>(10);
for(int i=0; i<7; ++i) {
secondCircular.add((double)i);
}
try(ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("circular_buffer.ser"))) {
objectOutputStream.writeObject(secondCircular);
objectOutputStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
@SuppressWarnings("unchecked")
Circular<Double> resultCircular=null;
try(ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("circular_buffer.ser"))) {
resultCircular=(Circular<Double>)objectInputStream.readObject();
objectInputStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
if(resultCircular!=null) {
System.out.println("/n"+resultCircular.toString());
}
}
}