2015-06-21 16 views
6

Ich versuche, einen einfachen Code zum Drucken von Zahlen in Folge zu schreiben. Szenario ist wie3 Threads Drucken von Zahlen in Folge

Thread Number 
T1  1 
T2  2 
T3  3 
T1  4 
T2  5 
T3  6 
T1  7 
T2  8 
T3  9 
...and so on. 

Hier die

ist
public class ThreadNumberPrinter { 

    Object monitor = new Object(); 
    AtomicInteger number = new AtomicInteger(1); 

    public static void main(String[] args) { 
     ThreadNumberPrinter tnp = new ThreadNumberPrinter(); 
     Thread t1 = new Thread(tnp.new Printer(1, 3)); 
     Thread t2 = new Thread(tnp.new Printer(2, 3)); 
     Thread t3 = new Thread(tnp.new Printer(3, 3)); 

     t3.start(); 
     t1.start(); 
     t2.start(); 
    } 

    class Printer implements Runnable { 

     int threadId; 
     int numOfThreads; 

     public Printer(int id, int nubOfThreads) { 
      threadId = id; 
      this.numOfThreads = nubOfThreads; 
     } 

     public void run() { 
      print(); 
     } 

     private void print() { 
      try { 
       while (true) { 
        Thread.sleep(1000l); 
        synchronized (monitor) { 
         if (number.get() % numOfThreads != threadId) { 
          monitor.wait(); 
         } else { 
          System.out.println("ThreadId [" + threadId 
            + "] printing -->" 
            + number.getAndIncrement()); 
          monitor.notifyAll(); 
         } 
        } 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     } 

    } 

Aber gerade nach dem 2. Thread ausgeführt und druckt die Nummer 2, erhält all Thread in der Warte Bühne und nichts wird gedruckt. Ich bin mir nicht sicher, wo ich falsch liege. Jede Hilfe würde sehr geschätzt werden.

+3

Dies kann eine nützliche Übung sein, um zu lernen, wie man Threads synchronisiert, aber es ist ein schlechtes Beispiel dafür, wie Threads verwendet werden sollen.Jedes Mal, wenn ein Programm eine Anzahl von Operationen muss in einer bestimmten Reihenfolge, die beste Art und Weise, es zu tun durchgeführt wird, ist _one_ Thread zu haben, den die Dinge in dieser Reihenfolge tut. Wenn Ihr Programm _effective USE_ von Threads macht, wird es Dinge geschehen, wo das Programm nicht wissen kann, und kümmert sich nicht um die Reihenfolge, in der sie auftreten. –

+0

wird ReentrantLock in diesem Szenario einen Vorteil gegenüber synchronisiert haben? –

Antwort

7

Nun, das Problem ist, dass Modulo 3 % 30 ist. Ändern Sie Ihre threadId s zu 0..2 statt 1..3 und hoffentlich sollte es funktionieren.

+1

Danke, es ist sehr traurig, dass es sehr offensichtlich war, aber ich konnte mir nicht vorstellen, warum ich es vorher nicht entdeckte. – Way2Go

0
package com.sourav.mock.Thread; 

    import java.util.concurrent.atomic.AtomicInteger; 

    public class ThreeThreadComunication implements Runnable { 
     AtomicInteger counter; 
     int[] array; 
     static final Object mutex = new Object(); 

     public ThreeThreadComunication(int[] array, AtomicInteger counter){ 
      this.counter = counter; 
      this.array = array; 
     } 

     @Override 
     public void run() { 
      int i = 0; 
      while(i < array.length){ 
       synchronized(mutex){ 
        if(Integer.parseInt(Thread.currentThread().getName()) == counter.get()){ 
         System.out.println(array[i]); 
         if(counter.get() == 3){ 
          counter.getAndSet(1); 
         }else{ 
          int c = counter.get(); 
          counter.getAndSet(++c); 
         } 
         i++; 
        } 

        mutex.notifyAll(); 
        try { 
         mutex.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 

package com.sourav.mock.Thread; 

import java.util.concurrent.atomic.AtomicInteger; 

public class ThreeThreadComunicationTest { 

    public static void main(String[] args) { 

     AtomicInteger counter = new AtomicInteger(1); 
     int[] array1 = new int[]{1, 4, 7}; 
     int[] array2 = new int[]{2, 5, 8}; 
     int[] array3 = new int[]{3, 6, 9}; 

     ThreeThreadComunication obj1 = new ThreeThreadComunication(array1, counter); 
     ThreeThreadComunication obj2 = new ThreeThreadComunication(array2, counter); 
     ThreeThreadComunication obj3 = new ThreeThreadComunication(array3, counter); 

     Thread t1 = new Thread(obj1, "1"); 
     Thread t2 = new Thread(obj2, "2"); 
     Thread t3 = new Thread(obj3, "3"); 

     t1.start(); 
     t2.start(); 
     t3.start(); 
    } 

} 
-1
public class ThreadTask implements Runnable { 

    private int counter; 
    private int threadID; 
    private final Object lock; 
    private int prev; 
    public ThreadTask(Object obj, int threadid, int counter){ 
     this.lock = obj; // monitor 
     this.threadID = threadid; //id of thread 
     this.counter = counter; 
     this.prev =threadid + 1; 
    } 

    public void run(){ 
     while(counter<100){ 
     synchronized(lock){ 
      if(counter == this.prev && this.threadID % 3 == this.threadID){ 
       System.out.println("T" + this.threadID + " = " + this.prev); 
       this.prev = this.prev + 3; 
      } 
      counter++; 
      lock.notifyAll(); 
      try{ 
       lock.wait(); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 
     } 
    } 
} 

public class ThreadMain { 

    static volatile int counter = 1; 
    public static void main(String args[]) throws InterruptedException{ 

     final Object lock = new Object(); 
     ThreadTask first = new ThreadTask(lock, 0, counter); 
     ThreadTask second = new ThreadTask(lock, 1, counter); 
     ThreadTask third = new ThreadTask(lock, 2, counter); 
     Thread t1 = new Thread(first, "first"); 
     Thread t2 = new Thread(second, "second"); 
     Thread t3 = new Thread(third, "third"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 
     t1.join(); 
     t2.join(); 
     t3.join(); 
    } 
} 
0
public class EvenOdd1 { 
    //public static String str ="str1"; 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     EvenOdd1 edd1 = new EvenOdd1(); 

     AbThread tr2 = new AbThread(0,edd1); 
     AbThread tr3 = new AbThread(1,edd1); 
     AbThread tr4 = new AbThread(2,edd1); 
     tr2.start(); 
     tr3.start(); 
     tr4.start(); 
    } 
} 
class AbThread extends Thread { 

     int mod; 
     int mod_count=1; 
     EvenOdd1 edd1; 
     public static int count=1; 
     int num_thread=3; 

     public AbThread(int mod,EvenOdd1 edd1){ 
      this.mod = mod; 
      this.edd1 = edd1; 

     } 

    public void run() 
    { 
     synchronized(edd1) 
     { 
      try{ 
      while(true){ 
       while(count%num_thread!=mod) 
        edd1.wait(); 

       if(count==30) 
        break; 

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

    } 


    public void print() 
    { 
     int val = mod==1?2*mod_count:(mod==2?3*mod_count:4*mod_count); 
     System.out.println(Thread.currentThread().getName() + " : " + val); 
     edd1.notifyAll(); 
     count=count+1; 
     this.mod_count++ ; 

    } 


} 
1

Im Folgenden Code verwendet die Logik des nächsten Thread Mitteilung an die Nummer zu drucken und sie dann um 1 erhöht wird und dann wieder die nächste Thread Meldung und dann in einem Wartezustand, bis einiger Thread benachrichtigt gehen es. Eg. T1 druckt zuerst den Wert und macht dann boolesche "zweite" wahr für T2, um die nächste Zahl zu drucken. T2 nach dem Drucken der Zahl macht Boolesche "dritte" wahr für T3. T3 macht das Gleiche, indem er boolesche "erste" wahr macht, damit T1 die nächste Zahl druckt.

T1 -> T2 -> T3 -> T1 -> T2 -> T3 -> ........ und so weiter.

public class Test{ 
    public static volatile int i = 0; 
    public static void main(String[] args) throws InterruptedException { 
    Object monitor = new Object(); 
    Notifier notifier = new Notifier(monitor); 
    Thread thread1 = new Thread(notifier, "T1"); 
    Thread thread2 = new Thread(notifier, "T2"); 
    Thread thread3 = new Thread(notifier, "T3"); 
    thread1.start(); 
    thread2.start(); 
    thread3.start(); 
    } 
} 



class Notifier implements Runnable { 

    private Object monitor = null; 
    private static int i = 1; 
    private static boolean first = true; 
    private static boolean second = false; 
    private static boolean third = false; 

    public Notifier(Object objcurr) { 
    this.monitor = objcurr; 
    } 

    @Override 
    public void run() { 
    try { 
     while (true) { 
     synchronized (monitor) { 
      String Tname = Thread.currentThread().getName(); 
      if (first && Tname.equalsIgnoreCase("T1")) { 
      print(); 
      first = false; 
      second = true; 
      monitor.notifyAll(); 
      monitor.wait(); 
      } else if (second && Tname.equalsIgnoreCase("T2")) { 
      print(); 
      second = false; 
      third = true; 
      monitor.notifyAll(); 
      monitor.wait(); 
      } else if (third && Tname.equalsIgnoreCase("T3")) { 
      print(); 
      third = false; 
      first = true; 
      monitor.notifyAll(); 
      monitor.wait(); 
      } else { 
      monitor.wait(); 
      } 
     } 
     Thread.sleep(1000); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

    private void print() { 
    System.out.println(Thread.currentThread().getName() + " - " + Notifier.i++); 
    } 
+0

Bitte geben Sie Ihren Antwortcode aus, nur die Antwort hilft nicht viel. – Jeet

+0

@Jeet - Ich hoffe, jetzt hilft die Beschreibung, den Code zu verstehen. –

+0

Vielen Dank für die Beschreibung. – Jeet

-1
package ThreadCoreConcepts; 

import java.util.ArrayList; 
import java.util.List; 

/** 
* 3 Thread T1,T2,T3 will print output {1,2,3 4,5,6 7,8,9} Where T1 will print 
* {1,4,7} , T2 will print { 2,5,8} and T3 will print {3,6,9} 
* 
* @author harsmahe 
* 
*/ 
public class ThreeThreadSequenceGen { 
    private volatile static int value = 1; 

    public static void main(String args[]) throws InterruptedException { 
     ThreeThreadSequenceGen gen = new ThreeThreadSequenceGen(); 
     Object mutex = new Object(); 
     Thread t1 = new Thread(gen.new RunThread(1, mutex)); 
     t1.setName("1"); 
     Thread t2 = new Thread(gen.new RunThread(2, mutex)); 
     t2.setName("2"); 
     Thread t3 = new Thread(gen.new RunThread(3, mutex)); 
     t3.setName("3"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 

    } 

    class RunThread implements Runnable { 
     private int start = 0; 
     private Object mutex; 
     private List<Integer> list = new ArrayList<Integer>(); 

     public RunThread(final int start, Object mutex) { 
      // TODO Auto-generated constructor stub 
      this.start = start; 
      this.mutex = mutex; 
     } 

     @Override 
     public void run() { 
      try { 
       while (value <= 9) { 
        // while (true) { 
        // TODO Auto-generated method stub 
        int name = Integer.valueOf(Thread.currentThread().getName()); 
        // System.out.println("[" + Thread.currentThread().getName() 
        // + "]"); 
        // notifyAll(); 

        synchronized (mutex) { 
         if (name == 1 && value == start) { 
          list.add(value); 
          System.out.println("[" + Thread.currentThread().getName() + "]" + value); 
          start = start + 3; 
          value++; 
          mutex.notifyAll(); 
          mutex.wait(); 
         } else if (name == 2 && value == start) { 
          System.out.println("[" + Thread.currentThread().getName() + "]" + value); 
          list.add(value); 
          start = start + 3; 
          value++; 
          mutex.notifyAll(); 
          mutex.wait(); 

         } else if (name == 3 && value == start) { 
          System.out.println("[" + Thread.currentThread().getName() + "]" + value); 
          list.add(value); 
          start = start + 3; 
          value++; 
          mutex.notifyAll(); 
          if (value < 9) { 
           mutex.wait(); 
          } 

         } else { 
          mutex.notifyAll(); 
          // mutex.wait(); 
         } 
        } 

       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       // System.out.println(list); 
      } 

     } 

    } 
} 

    enter code here 
0
public class PrintThreadsSequentially { 

static int number = 1; 
static final int PRINT_NUMBERS_UPTO = 20; 
static Object lock = new Object(); 

static class SequentialThread extends Thread { 
    int remainder = 0; 
    int noOfThreads = 0; 

    public SequentialThread(String name, int remainder, int noOfThreads) { 
     super(name); 
     this.remainder = remainder; 
     this.noOfThreads = noOfThreads; 
    } 

    @Override 
    public void run() { 
     while (number < PRINT_NUMBERS_UPTO) { 
      synchronized (lock) { 
       while (number % noOfThreads != remainder) { // wait for numbers other than remainder 
        try { 
         lock.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
       System.out.println(getName() + " value " + number); 
       number++; 
       lock.notifyAll(); 
      } 
     } 
    } 
} 

public static void main(String[] args) { 
    SequentialThread first = new SequentialThread("First Thread", 0, 4); 
    SequentialThread second = new SequentialThread("Second Thread", 1, 4); 
    SequentialThread third = new SequentialThread("Third Thread", 2, 4); 
    SequentialThread fourth = new SequentialThread("Fourth Thread", 3, 4); 
    first.start(); second.start(); third.start(); fourth.start(); 
} 

}

0

Die ThreadSynchronization Klasse verwendet werden können Zahlen zwischen drucken 'n' nicht. von Threads in Folge. Die Logik besteht darin, ein gemeinsames Objekt zwischen jedem der aufeinanderfolgenden Threads zu erstellen und 'wait', 'notify' zu verwenden, um die Zahlen nacheinander auszugeben. Hinweis: Der letzte Thread teilt ein Objekt mit dem ersten Thread.

Sie können den Wert für 'maxThreads' ändern, um die Anzahl der Threads im Programm vor der Ausführung zu erhöhen oder zu verringern.

importieren java.util.ArrayList; importieren java.util.List;

public class ThreadSynchronization {

public static int i = 1; 
public static final int maxThreads = 10; 

public static void main(String[] args) { 
    List<Object> list = new ArrayList<>(); 
    for (int i = 0; i < maxThreads; i++) { 
     list.add(new Object()); 
    } 
    Object currObject = list.get(maxThreads - 1); 
    for (int i = 0; i < maxThreads; i++) { 
     Object nextObject = list.get(i); 
     RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false); 
     Thread th = new Thread(a); 
     th.setName("Thread - " + (i + 1)); 
     th.start(); 
     currObject = list.get(i); 
    } 
} 

}

Klasse RunnableClass implementiert Runnable {

private Object currObject; 
private Object nextObject; 
private boolean firstThread; 

public RunnableClass(Object currObject, Object nextObject, boolean first) { 
    this.currObject = currObject; 
    this.nextObject = nextObject; 
    this.firstThread = first; 
} 

@Override 
public void run() { 
    int i = 0; 
    try { 
     if (firstThread) { 
      Thread.sleep(5000); 
      firstThread = false; 
      System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++); 
      synchronized (nextObject) { 
       nextObject.notify(); 
      } 
     } 
     while (i++ < Integer.MAX_VALUE) { 
      synchronized (currObject) { 
       currObject.wait(); 
      } 
      System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++); 
      Thread.sleep(1000); 
      synchronized (nextObject) { 
       nextObject.notify(); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

0
public class TestClass { 

    private volatile Integer count = 1; 
    private volatile Integer threadIdToRun = 1; 
    private Object object = new Object(); 

    public static void main(String[] args) { 

     TestClass testClass = new TestClass(); 
     Thread t1 = new Thread(testClass.new Printer(1)); 
     Thread t2 = new Thread(testClass.new Printer(2)); 
     Thread t3 = new Thread(testClass.new Printer(3)); 

     t1.start(); 
     t2.start(); 
     t3.start(); 
    } 

    class Printer implements Runnable { 

     private int threadId; 

     public Printer(int threadId) { 
      super(); 
      this.threadId = threadId; 
     } 

     @Override 
     public void run() { 
      try { 
       while (count <= 20) { 
        synchronized (object) { 
         if (threadId != threadIdToRun) { 
          object.wait(); 
         } else { 
          System.out.println("Thread " + threadId + " printed " + count); 
          count += 1; 

          if (threadId == 1) 
           threadIdToRun = 2; 
          else if (threadId == 2) 
           threadIdToRun = 3; 
          else if (threadId == 3) 
           threadIdToRun = 1; 

          object.notifyAll(); 
         } 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
} 

Above Programm gibt Ausg ut

Thread 1 printed 1 
Thread 2 printed 2 
Thread 3 printed 3 
Thread 1 printed 4 
Thread 2 printed 5 
Thread 3 printed 6 
Thread 1 printed 7 
Thread 2 printed 8 
Thread 3 printed 9 
Thread 1 printed 10 
Thread 2 printed 11 
Thread 3 printed 12 
Thread 1 printed 13 
Thread 2 printed 14 
Thread 3 printed 15 
Thread 1 printed 16 
Thread 2 printed 17 
Thread 3 printed 18 
Thread 1 printed 19 
Thread 2 printed 20 
Verwandte Themen