alifangelo
23-10-2008, 17:15
Ciao a tutti, sto cercando di implemetare un semaforo FIFO cioè ogni volta che si esegue la signal viene risvegliato il thread che è in attesa da piu tempo.
L'idea è quella di creare un array circolare di object e mettere in cima i thread che si bloccano e sbloccarli dalla coda ottendo così la gestione FIFO.
Vi espongo il codice che sarà sicuramente piu chiaro
public class Semaphore {
public static final int SIZE = 100;
private int count = 0;
private String name;
private Object coda[] = null;
private int tail = 0;
private int head = 0;
public Semaphore(int count, String name) {
this.count = count;
this.name = name;
this.coda = new Object[SIZE];
for (int i = 0; i < SIZE; i++)
coda[i] = new Object();
}
public void swait() {
int heado;
synchronized (coda[head]) {
count -= 1;
if (count < 0)
try {
heado = head;
head = (head + 1) % SIZE;
System.out.println( " - bloccato "+thread.currentThread());
coda[heado].wait();
}
catch (Exception e) {
System.out.println( e+" - eccez. nella swait";
}
}
}
public void signal() {
synchronized (coda[tail]) {
count += 1;
if (count <= 0) {
coda[tail].notify();
tail = (tail + 1) % SIZE;
}
System.out.println(" fine signal: " + Thread.currentThread());
}
}
}
//codice thread
public class Mythread extends Thread{
private Semaphore semaforo;
public Mythread( Semaphore semaforo){
this.semaforo=semaforo;
}
public void run (){
semaforo.swait();
System.out.println( " sto dormendo " + Thread.currentThread());
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
System.out.println( " eccez. nella sleep " + Thread.currentThread());
e.printStackTrace();
}
semaforo.signal();
}
}
// il MAIN
public class Test {
public static void main(String[] args){
Semaphore s=new Semaphore(1,"semaforo");
Mythread A= new Mythread(s);
A.start();
Mythread B= new Mythread(s);
B.start();
Mythread C= new Mythread(s);
C.start();
Mythread D= new Mythread(s);
D.start();
Mythread E= new Mythread(s);
E.start();
Mythread F= new Mythread(s);
F.start();
}
}
il problema è che nella swait viene generata un'eccezione quando eseguo coda[heado].wait(); L'eccezione è java.lang.IllegalMonitorStateException ma non riesco a capire il perchè, esce random, cioè alcune volte va altre no.
vi posto un run con cosa mi esce
sto dormendo Thread[Thread-0,5,main]
bloccato Thread[Thread-2,5,main]
bloccato Thread[Thread-3,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-3,5,main]
sto dormendo Thread[Thread-3,5,main]
bloccato Thread[Thread-4,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-4,5,main]
sto dormendo Thread[Thread-4,5,main]
bloccato Thread[Thread-5,5,main]
bloccato Thread[Thread-1,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-1,5,main]
sto dormendo Thread[Thread-1,5,main]
fine signal:Thread[Thread-0,5,main]
sto dormendo Thread[Thread-2,5,main]
fine signal: count = -3Thread[Thread-4,5,main]
fine signal: count = -2Thread[Thread-3,5,main]
fine signal: count = -1Thread[Thread-1,5,main]
sto dormendo Thread[Thread-5,5,main]
fine signal: count = 0Thread[Thread-2,5,main]
fine signal: count = 1Thread[Thread-5,5,main]
Se qualcuno saprebbe darmi una spiegazione gliene sarei grato.
Vi ringrazio anche se solo avete letto tutto quello che ho scritto :D
Già che ci sono volevo chiedervi se dopo che un thread viene risvegliato da una notify prosegue il suo codice dopo la wait giusto? Ma a quel punto ha di nuovo il lock dell'oggetto ?
L'idea è quella di creare un array circolare di object e mettere in cima i thread che si bloccano e sbloccarli dalla coda ottendo così la gestione FIFO.
Vi espongo il codice che sarà sicuramente piu chiaro
public class Semaphore {
public static final int SIZE = 100;
private int count = 0;
private String name;
private Object coda[] = null;
private int tail = 0;
private int head = 0;
public Semaphore(int count, String name) {
this.count = count;
this.name = name;
this.coda = new Object[SIZE];
for (int i = 0; i < SIZE; i++)
coda[i] = new Object();
}
public void swait() {
int heado;
synchronized (coda[head]) {
count -= 1;
if (count < 0)
try {
heado = head;
head = (head + 1) % SIZE;
System.out.println( " - bloccato "+thread.currentThread());
coda[heado].wait();
}
catch (Exception e) {
System.out.println( e+" - eccez. nella swait";
}
}
}
public void signal() {
synchronized (coda[tail]) {
count += 1;
if (count <= 0) {
coda[tail].notify();
tail = (tail + 1) % SIZE;
}
System.out.println(" fine signal: " + Thread.currentThread());
}
}
}
//codice thread
public class Mythread extends Thread{
private Semaphore semaforo;
public Mythread( Semaphore semaforo){
this.semaforo=semaforo;
}
public void run (){
semaforo.swait();
System.out.println( " sto dormendo " + Thread.currentThread());
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
System.out.println( " eccez. nella sleep " + Thread.currentThread());
e.printStackTrace();
}
semaforo.signal();
}
}
// il MAIN
public class Test {
public static void main(String[] args){
Semaphore s=new Semaphore(1,"semaforo");
Mythread A= new Mythread(s);
A.start();
Mythread B= new Mythread(s);
B.start();
Mythread C= new Mythread(s);
C.start();
Mythread D= new Mythread(s);
D.start();
Mythread E= new Mythread(s);
E.start();
Mythread F= new Mythread(s);
F.start();
}
}
il problema è che nella swait viene generata un'eccezione quando eseguo coda[heado].wait(); L'eccezione è java.lang.IllegalMonitorStateException ma non riesco a capire il perchè, esce random, cioè alcune volte va altre no.
vi posto un run con cosa mi esce
sto dormendo Thread[Thread-0,5,main]
bloccato Thread[Thread-2,5,main]
bloccato Thread[Thread-3,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-3,5,main]
sto dormendo Thread[Thread-3,5,main]
bloccato Thread[Thread-4,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-4,5,main]
sto dormendo Thread[Thread-4,5,main]
bloccato Thread[Thread-5,5,main]
bloccato Thread[Thread-1,5,main]
java.lang.IllegalMonitorStateException - eccez. nella swait Thread[Thread-1,5,main]
sto dormendo Thread[Thread-1,5,main]
fine signal:Thread[Thread-0,5,main]
sto dormendo Thread[Thread-2,5,main]
fine signal: count = -3Thread[Thread-4,5,main]
fine signal: count = -2Thread[Thread-3,5,main]
fine signal: count = -1Thread[Thread-1,5,main]
sto dormendo Thread[Thread-5,5,main]
fine signal: count = 0Thread[Thread-2,5,main]
fine signal: count = 1Thread[Thread-5,5,main]
Se qualcuno saprebbe darmi una spiegazione gliene sarei grato.
Vi ringrazio anche se solo avete letto tutto quello che ho scritto :D
Già che ci sono volevo chiedervi se dopo che un thread viene risvegliato da una notify prosegue il suo codice dopo la wait giusto? Ma a quel punto ha di nuovo il lock dell'oggetto ?