2015-06-21 199 views
6

我正在尝试编写一个简单的代码来按顺序打印数字。情景就像是3主题按顺序打印数字

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

这里是

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(); 
      } 
     } 

     } 

    } 

但是刚过2号线运行,并打印数字2,所有线程进入观望阶段,并没有被打印出来。我不确定我做错了什么。 任何帮助将不胜感激。

+3

这可能是一个学习如何同步线程的有用练习,但它是线程如何使用的一个_bad示例。每当一个程序需要以某种特定的顺序执行一些操作时,最好的方法就是让_one_线程按照该顺序执行这些操作。当你的程序有效地使用线程时,会发生一些事情发生在程序无法知道并且不关心它们发生的顺序的地方。 –

+0

在这种情况下使用ReentrantLock会有什么优势吗? –

回答

7

那么,问题是模3 % 30。更改您的threadId s到0..2而不是1..3,并希望它应该工作。

+1

谢谢,这是非常可悲的,这是非常明显的,但想不到为什么我早点发现它。 – 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

下面的代码使用通知下一个线程打印的号码,然后递增1,然后再通知下一个线程,然后在等待状态去,直到某个线程通知的逻辑它。例如, T1首先打印该值,然后使T2的布尔值“秒”为真来打印下一个数字。打印数字后的T2使得布尔值“T3”为真。 T3通过为T1打印下一个数字的布尔值“first”为true来做同样的事情。

T1→T2→T3→T1→T2→T3→......等等。

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

请详细说明您的答案代码只有答案没有多大帮助。 – Jeet

+0

@Jeet - 我希望现在的描述将有助于理解代码。 –

+0

感谢您的描述。 – 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

的ThreadSynchronization类可用于之间打印数 'n' 个不。顺序的线程。 逻辑是在每个连续线程之间创建一个公共对象,并使用'wait','notify'按顺序打印数字。 注意:最后一个线程将与第一个线程共享一个对象。

在运行程序之前,可以更改'maxThreads'值以增加或减少程序中的线程数。

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

公共类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); 
    } 
} 

}

类RunnableClass实现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(); 
      } 

     } 
    } 
} 

上述程序使OUTP 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