2016-04-25 13 views
0

ich diesen Code geschrieben haben, ein Gerät zu blockieren Warteschlange:Wie macht man das Objekt für alle Threads sichtbar und editierbar?

public class MyBlockingQueue extends Thread{ 

final private List <Integer> queue; 

    public MyBlockingQueue(){ 
     queue = new LinkedList<Integer>(); 
    } 

    public synchronized int size() { 

      return queue.size(); 

    } 

    public synchronized void enqueue(int num) 
    throws InterruptedException { 

    this.queue.add(num); 
    System.out.println(getName()+" "+num+" added"); 
    notify(); 
    } 

    public synchronized int dequeue() 
    throws InterruptedException{ 
     while(queue.size() == 0) 
      wait(); 

    return this.queue.remove(0); 
    } 

1.Ich versucht haben, zwei Threads zu machen und sie zwingen, eine bestimmte Anzahl in die Warteschlange hinzufügen und entfernen Sie sie dann. Leider scheint jeder Thread sein eigenes Objekt zu haben. Wie kann ich den Code so ändern, dass beide Threads dasselbe Objekt behandeln und synchron zur selben blockierenden Warteschlange hinzugefügt/entfernt werden?

2.Habe ich die Dequeue-Funktion korrekt geschrieben (so dass, wenn ein Thread die letzte Nummer aus der Warteschlange entfernt und die Warteschlangengröße jetzt Null ist, warten andere Threads, bis die Enqueue sie benachrichtigt)?

das ist mein Tester:

public class Main { 
    //checks the blocking queue 
public static void main(String[] args) throws InterruptedException { 
    final MyBlockingQueue mine = new MyBlockingQueue(); 
    Thread t1 = new Thread(){ 
     public void run(){ 
      try { 


       mine.enqueue((int)(Math.random()*1000)); 
       System.out.println(getName()+"<- enter"); 

       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }; 
     } 
    }; 

    Thread t2 = new Thread(){ 
     public void run(){ 
      try { 


       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 

      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 

    Thread t3 = new Thread(){ 
     public void run(){ 
      try { 


       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 

      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t4 = new Thread(){ 
     public void run(){ 
      try { 

       mine.enqueue((int)(Math.random()*1000)); 
       System.out.println(getName()+"<-enter"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t5 = new Thread(){ 
     public void run(){ 
      try { 

       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 


    Thread t6 = new Thread(){ 
     public void run(){ 
      System.out.println("thread 6 of entering began, should release last thread of remove"); 
      try { 

       mine.enqueue((int)(Math.random()*1000)); 
       System.out.println(getName()+"<-enter"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t7 = new Thread(){ 
     public void run(){ 
      try { 

       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t8 = new Thread(){ 
     public void run(){ 
      try { 

       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t9 = new Thread(){ 
     public void run(){ 
      try { 

       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t10 = new Thread(){ 
     public void run(){ 
      try { 

       mine.dequeue(); 
       System.out.println(getName()+"<-remove"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 
    Thread t11 = new Thread(){ 
     public void run(){ 
      System.out.println("thread 11 come to help, this comment before entering, after that we should see one add one remove"); 
      try { 

       mine.enqueue((int)(Math.random()*1000)); 
       System.out.println(getName()+"<-enter"); 


       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 

    t1.start(); 
    t2.start(); 
    t3.start(); 
    Thread.sleep(5000); 

    t4.start();//will the remove wai for the enter 
    Thread.sleep(5000); 
    /////4 tries to remove, one enter 
    t5.start(); //requesting to remove before have something 
    t7.start(); 
    t8.start(); 
    t9.start(); 
    t10.start(); 
    Thread.sleep(5000); 
    t6.start(); 
    Thread.sleep(20000);//after 20 sec, t11 come to help 
    t11.start(); 

} 

} 

hier ist die Ausgabe:

Thread-0 enqueued 1 
Thread-1<- enter 
Thread-0 dequeued 1 
Thread-2<-remove 
Thread-0 enqueued 4 
Thread-0 dequeued 4 
Thread-3<-remove 
Thread-4<-enter 
thread 6 of entering began, should release last thread of remove 
Thread-0 enqueued 6 
Thread-0 dequeued 6 
Thread-5<-remove 
Thread-6<-enter 
thread 11 come to help, this comment before entering, after that we should see one add one remove 
Thread-0 enqueued 11 
Thread-0 dequeued 11 
Thread-8<-remove 
Thread-11<-enter 
+1

Warum 'erstreckt Thread'? Eine Warteschlange ist keine Art von Thread. –

+0

Re, "Es scheint, als ob jeder Thread sein eigenes Objekt hat. Wie kann ich den Code ändern, so dass beide Threads das gleiche Objekt behandeln?" Sie haben uns keinen Code gezeigt, der Ihre 'MyBlockingQueue'-Klasse verwendet. Daher ist es schwer zu sagen, was mit diesem Code falsch ist oder nicht. –

+0

Entschuldigung, ich habe einen Testcode beigefügt – adi

Antwort

0

Sie müssen die Warteschlange statisch oder übergeben Sie das Objekt auf die Fäden bei der Initialisierung machen. Wenn Sie dies nicht tun, werden die beiden Threads in separaten Warteschlangen eingereiht/entfernt.

+0

Was sollte ich statische - die Liste oder die blockierende Warteschlange? – adi

+0

@Limmen hat genau geschrieben, was sollte statische Warteschlange in Ihrem MyBlockingQueue-Klasse sein – mariusz2108

+0

oh Entschuldigung, Warteschlange ist meine Liste. Das habe ich nicht bemerkt. Danke! – adi

-1

Zum Beispiel:

public class MyBlockingQueue extends Thread { 

    final private static List<Integer> queue = new LinkedList<Integer>(); 

    public synchronized int size() { 

     return MyBlockingQueue.queue.size(); 

    } 

    public synchronized void enqueue(int num) throws InterruptedException { 

     MyBlockingQueue.queue.add(num); 
     System.out.println(getName() + " enqueued " + num); 
     notify(); 
    } 

    public synchronized int dequeue() throws InterruptedException { 
     while (MyBlockingQueue.queue.size() == 0) { 
      wait(); 
     } 
     System.out.println(getName() + " dequeued " + MyBlockingQueue.queue.get(0)); 
     return MyBlockingQueue.queue.remove(0); 
    } 
} 
+0

Ich denke, dass ich es geschafft habe, es anders zu managen, aber danke !! Übrigens, Ihr Code verwaltet das Problem, dass "Wenn ein Thread die letzte Nummer aus der Warteschlange entfernt und die Warteschlangengröße jetzt Null ist, werden andere Threads warten, bis die Enqueue sie benachrichtigt"? – adi

+0

Es ist nicht meins, es ist nur Ihr Code mit den oben genannten Modifikationen empfohlen. Gute und richtige Beispiele finden Sie in der Quelle der nächsten Dateien: ArrayBlockingQueue DelayQueue LinkedBlockingQueue PriorityBlockingQueue SynchronousQueue. Innerhalb von java.util.concurrent Paket –

+0

Vielen Dank für die Hilfe – adi