Benutzer-Werkzeuge

Webseiten-Werkzeuge


api:documentation:threads:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
api:documentation:threads:start [2024/10/28 20:34] – [Synchronized-Methode] martinapi:documentation:threads:start [2025/03/05 10:26] (aktuell) – [synchronized-Block] martin
Zeile 174: Zeile 174:
          if(i % (increment/10) == 0) println("Thread " + index + ": " + i);          if(i % (increment/10) == 0) println("Thread " + index + ": " + i);
          counter.increment();          counter.increment();
 +      }
 +      println("Thread " + index + " done. Counter: " + counter.counter);
 +   }
 +
 +}
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +
 +===== Die Klasse Semaphore =====
 +<WRAP center round info 80%>
 +Ein **Semaphor** ist ein Objekt, das einen Zähler enthält, dessen Wert angibt, von wie vielen Prozessen ein kritischer Abschnitt im Augenblick gerade noch betreten werden darf. \\  (**Bem.:** Eine andere Interpretation besteht darin, dass es $n$ gleichartig Ressourcen gibt. Der Wert des Zählers gibt an, wie viele im Augenblick gerade zur Verfügung stehen.) \\ \\ Der Semaphor besitzt zwei Methoden:
 +  * ''aquire()'' prüft, ob der Zähler größer als 0 ist. 
 +    * Ist dies der Fall, so wird der Zähler um eins erniedrigt und mit der danach folgenden Anweisung fortgefahren. Dem Prozess wird damit das Betreten des kritischen Bereichs gestattet.
 +    * Ist dies **nicht** der Fall, so wird der Prozess in einen Wartezustand versetzt. \\ 
 +  * ''release()'' prüft, ob es zu diesem Semaphor Prozesse im Wartezustand gibt.
 +    * Falls dies der Fall ist, wir einer davon "aufgeweckt" und darf damit den kritischen Bereich betreten.
 +    * Ist dies **nicht** der Fall, so wird der Zähler um 1 erhöht.
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 60vh; width: 90%" data-java-online="{'withBottomPanel': false, 'id': 'ThreadTest2'}">
 +
 +<script type="text/plain" title="Semaphore1.java">
 +Counter counter = new Counter();
 +Semaphore semaphore = new Semaphore(1);
 +
 +for (int i = 0; i < 3; i++) {
 +   Incrementer inc = new Incrementer(counter, 1e6, i, semaphore);
 +   Thread t = new Thread(inc);
 +   t.setName("Thread " + i);
 +   t.start();
 +}
 +
 +class Counter {
 +   long counter = 0;
 +
 +   public synchronized void increment() {   // <-- mit Schlüsselwort synchronized!
 +      long i = counter;
 +      i++;
 +      counter = i;
 +   }
 +}
 +
 +
 +class Incrementer implements Runnable {
 +   
 +   Counter counter;
 +   long increment = 0;
 +   int index;
 +   Semaphore semaphore;
 +
 +   Incrementer(Counter counter, long increment, int index, Semaphore semaphore) {
 +      this.increment = increment;
 +      this.counter = counter;
 +      this.index = index;
 +      this.semaphore = semaphore;
 +   }
 +
 +   public void run() {
 +      for (long i = 0; i < increment; i++) {
 +         if(i % (increment / 10) == 0) println("Thread " + index + ": " + i);
 +         semaphore.aquire();
 +         counter.increment();
 +         semaphore.release();
       }       }
       println("Thread " + index + " done. Counter: " + counter.counter);       println("Thread " + index + " done. Counter: " + counter.counter);
Zeile 187: Zeile 256:
  
 ===== Monitorkonzept ===== ===== Monitorkonzept =====
 +<HTML>
 +
 +<div class="java-online" style="height: 60vh; width: 90%" data-java-online="{'withBottomPanel': true, 'id': 'ConsumerProducer134'}">
 +
 +<script type="text/plain" title="Main.java">
 +BlockingQueue<String> queue = new BlockingQueue<>(5);
 +
 +for (int i = 0; i < 3; i++) {
 +   new Producer(queue, 100, i);
 +   new MyConsumer(queue, 100, i);
 +}
 +
 +while (true);
 +
 +
 +class Producer implements Runnable {
 +   BlockingQueue<String> queue;
 +   int count;
 +   int producerIndex;
 +
 +   Producer(BlockingQueue<String> queue, int count, int producerIndex) {
 +      this.queue = queue;
 +      this.count = count;
 +      this.producerIndex = producerIndex;
 +      Thread t = new Thread(this);
 +      t.setName("Producer " + producerIndex);
 +      t.start();
 +   }
 +
 +   public void run() {
 +      while (count > 0) {
 +         queue.put(this.producerIndex + "/" + this.count);
 +         println("P " + this.producerIndex + " added " + count, Color.lightblue); 
 +
 +         count--;
 +      }
 +   }
 +
 +}
 +
 +class MyConsumer implements Runnable {
 +   BlockingQueue<String> queue;
 +   int count;
 +   int consumerIndex;
 +
 +   MyConsumer(BlockingQueue<String> queue, int count, int consumerIndex) {
 +      this.queue = queue;
 +      this.count = count;
 +      this.consumerIndex = consumerIndex;
 +      Thread t = new Thread(this);
 +      t.setName("Consumer " + consumerIndex);
 +      t.start();
 +   }
 +
 +   public void run() {
 +      while (count > 0) {
 +         String s = queue.take();
 +         println("C " + this.consumerIndex + " removed " + s, Color.lightgreen); 
 +         count--;
 +      }
 +   }
 +
 +}
 +</script>
 +
 +
 +<script type="text/plain" title="BlockingQueue.java">
 +public class BlockingQueue < T extends Object > {
 +
 +   private Queue<T> queue = new LinkedList<T>();
 +   private int capacity;
 +
 +   public BlockingQueue(int capacity) {
 +      this.capacity = capacity;
 +   }
 +
 +   public synchronized void put(T element) {
 +      while (queue.size() == capacity) {
 +         wait();
 +      }
 +
 +      queue.add(element);
 +      notify(); // notifyAll() for multiple producer/consumer threads
 +   }
 +
 +   public synchronized T take() {
 +      while (queue.isEmpty()) {
 +         wait();
 +      }
 +
 +      T item = queue.remove();
 +      notify(); // notifyAll() for multiple producer/consumer threads
 +      return item;
 +   }
 +   
 +   public int size() {
 +      return queue.size();
 +   }
 +}
 +</script>
 +</div>
 +</HTML>
 +
 +===== synchronized-Block =====
 +<HTML>
 +
 +<div class="java-online" style="height: 60vh; width: 90%" data-java-online="{'withBottomPanel': false, 'id': 'ThreadTest2'}">
 +
 +<script type="text/plain" title="ThreadTest1.java">
 +
 +Counter counter = new Counter();
 +
 +for (int i = 0; i < 3; i++) {
 +   Incrementer inc = new Incrementer(counter, 1e6, i);
 +   Thread t = new Thread(inc);
 +   t.setName("Thread " + i);
 +   t.start();
 +}
 +
 +class Counter {
 +   long counter = 0;
 +}
 +
 +
 +class Incrementer implements Runnable {
 +   
 +   Counter counter;
 +   long increment = 0;
 +   int index;
 +
 +   Incrementer(Counter counter, long increment, int index) {
 +      this.increment = increment;
 +      this.counter = counter;
 +      this.index = index;
 +   }
 +
 +   public void run() {
 +      for (long i = 0; i < increment; i++) {
 +         if(i % (increment/10) == 0) println("Thread " + index + ": " + i);
 +         
 +         synchronized (counter) {
 +            long i = counter.counter;
 +            i++;
 +            counter.counter = i;
 +         }
 +         
 +      }
 +      println("Thread " + index + " done. Counter: " + counter.counter);
 +   }
 +
 +}
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
  
api/documentation/threads/start.1730147643.txt.gz · Zuletzt geändert: 2024/10/28 20:34 von martin