【问题标题】:3 Threads Printing numbers in sequence3 线程按顺序打印数字
【发布时间】:2015-06-21 11:44:14
【问题描述】:

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

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 之后,所有线程都进入等待阶段并且没有打印任何内容。我不确定我在哪里做错了。 任何帮助将不胜感激。

【问题讨论】:

  • 这可能是学习如何同步线程的有用练习,但它是一个糟糕的示例,说明了如何使用线程。每当一个程序需要以某种特定顺序执行许多操作时,最好的方法是让 一个 线程按该顺序执行操作。当您的程序有效地使用线程时,会发生一些程序无法知道并且不关心它们发生的顺序的事情。
  • 在这种情况下使用 ReentrantLock 是否比同步有任何优势?
  • n 线程的通用解决方案:stackoverflow.com/a/49714113/1216775

标签: java multithreading


【解决方案1】:
  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();
            }

        }
    }
}

上面的程序给出了输出

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

【讨论】:

  • 不错且可销售的解决方案!
【解决方案2】:

嗯,问题在于 3 % 3 的模数是 0。将您的 threadIds 更改为 0..2 而不是 1..3,希望它应该可以工作。

【讨论】:

  • 谢谢,很遗憾,很明显,但想不出我为什么早点发现它。
【解决方案3】:

虽然这是使用线程的一种不好的方式,但如果我们仍然想要它,一个通用的解决方案可以是拥有一个工作线程来存储它的 id:

class Worker extends Thread {
    private final ResourceLock resourceLock;
    private final int threadNumber;
    private final AtomicInteger counter;
    private volatile boolean running = true;
    public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
        this.resourceLock = resourceLock;
        this.threadNumber = threadNumber;
        this.counter = counter;
    }
    @Override
    public void run() {
        while (running) {
            try {
                synchronized (resourceLock) {
                    while (resourceLock.flag != threadNumber) {
                        resourceLock.wait();
                    }
                    System.out.println("Thread:" + threadNumber + " value: " + counter.incrementAndGet());
                    Thread.sleep(1000);
                    resourceLock.flag = (threadNumber + 1) % resourceLock.threadsCount;
                    resourceLock.notifyAll();
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
        }
    }
    public void shutdown() {
        running = false;
    }
}

ResourceLock 类将存储标志和最大线程数:

class ResourceLock {
    public volatile int flag;
    public final int threadsCount;

    public ResourceLock(int threadsCount) {
        this.flag = 0;
        this.threadsCount = threadsCount;
    }
}

然后主类可以如下使用它:

public static void main(String[] args) throws InterruptedException {
        final int threadsCount = 3;
        final ResourceLock lock = new ResourceLock(threadsCount);
        Worker[] threads = new Worker[threadsCount];
        final AtomicInteger counter = new AtomicInteger(0);
        for(int i=0; i<threadsCount; i++) {
            threads[i] = new Worker(lock, i, counter);
            threads[i].start();
        }
        Thread.sleep(10000);
        System.out.println("Will try to shutdown now...");
        for(Worker worker: threads) {
            worker.shutdown();
        }
    }

在这里,经过一定的延迟后,我们可能希望停止计数,并且 worker 中的方法 shutdown 提供了此规定。

【讨论】:

    【解决方案4】:

    下面的代码使用通知下一个线程打印数字然后将其加1然后再次通知下一个线程然后进入等待状态直到某个线程通知它的逻辑。 例如。 T1 首先打印该值,然后使布尔值“第二”为真,以便 T2 打印下一个数字。打印数字后的 T2 使 T3 的布尔值“第三”为真。 T3 通过将布尔值“first”设置为 true 以使 T1 打印下一个数字来执行相同的操作。

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

    【讨论】:

    • 请详细说明您的答案代码,仅答案没有多大帮助。
    • @Jeet - 我希望现在的描述将有助于理解代码。
    • 感谢您的描述。
    • 这里的布尔变量不是线程安全的,需要使用原子变量或者易失变量。
    • 上面的例子不需要检查 Tname.equals 因为所有其他线程都在等到那里。
    【解决方案5】:

    这个怎么样?

    public class PrintNumbers implements Runnable {
    
        public static final int NO_OF_THREADS = 3;
        public static final int MAX_DIGIT = 20;
        public static final String THREAD_NAME_PREFIX = "t";
    
        volatile int current = 1;
        private Object lock = new Object();
    
        public static void main(String[] args) {
            PrintNumbers printNumbers = new PrintNumbers();
            for (int i = 1; i <= NO_OF_THREADS; i++) {
                new Thread(printNumbers, THREAD_NAME_PREFIX + i).start();
            }
        }
    
        @Override
        public void run() {
            String printThread;
            while (current < MAX_DIGIT) {
                synchronized (lock) {
                    if (current % NO_OF_THREADS != 0) {
                        printThread = THREAD_NAME_PREFIX + current % NO_OF_THREADS;
                    } else {
                        printThread = THREAD_NAME_PREFIX + NO_OF_THREADS;
                    }
    
                    if (!printThread.equals(Thread.currentThread().getName())) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                    if (printThread.equals(Thread.currentThread().getName())) {
                        System.out.println(String.format("Thread %s : %s", Thread.currentThread().getName(), current));
                        current = current + 1;
                    }
    
                    lock.notifyAll();
                }
            }
        }
    }
    

    【讨论】:

      【解决方案6】:
          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();
          }
      
      }
      

      【讨论】:

        【解决方案7】:
        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++ ;
        
            }
        
        
        }
        

        【讨论】:

          【解决方案8】:
          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();
          }
          

          }

          【讨论】:

          • 这个方法最终会打印出比要求更多的值。所有处于 Waiting 状态的线程最终都会打印出超出要求的数量。
          【解决方案9】:

          ThreadSynchronization 类可用于打印 'n' 号之间的数字。线程的顺序。 逻辑是在每个连续线程之间创建一个公共对象,并使用“等待”、“通知”来按顺序打印数字。 注意:最后一个线程将与第一个线程共享一个对象。

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

          import java.util.ArrayList;
          import 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);
                  }
              }
          
          }
          
          class RunnableClass implements 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();
                  }
              }
          }
          

          【讨论】:

            【解决方案10】:

            我已经尝试过使用三个线程按顺序打印的简单方法,效果很好。

            public class AppPrint123 {
            
                static int count = 1;
                static int counter = 1;
                static Object lock = new Object();
            
                public static void main(String[] args) {
            
                    Thread t1 = new Thread(new Runnable() {
            
                        public void run() {
                            while (true) {
                                synchronized (lock) {
            
                                    try {
                                        Thread.sleep(100);
                                        while (count != 1) {
                                            lock.wait();
                                        }
                                        System.out.println(Thread.currentThread().getName() + ": " + counter);
                                        count++;
                                        counter++;
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    lock.notifyAll();
                                }
                            }
            
                        }
            
                    }, "T1");
            
                    Thread t2 = new Thread(new Runnable() {
            
                        public void run() {
                            while (true) {
                                synchronized (lock) {
            
                                    try {
                                        Thread.sleep(100);
                                        while (count != 2) {
                                            lock.wait();
                                        }
                                        System.out.println(Thread.currentThread().getName() + ": " + counter);
                                        counter++;
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    lock.notifyAll();
                                }
                            }
                        }
            
                    }, "T2");
            
                    Thread t3 = new Thread(new Runnable() {
            
                        public void run() {
                            while (true) {
                                synchronized (lock) {
                                    try {
                                        Thread.sleep(100);
                                        while (count != 3) {
                                            lock.wait();
                                        }
                                        System.out.println(Thread.currentThread().getName() + ": " + counter);
                                        count = count - 2;
                                        counter++;
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    lock.notifyAll();
                                }
                            }
                        }
            
                    }, "T3");
            
                    t1.start();
                    t2.start();
                    t3.start();
            
                }
            }
            

            如果您想使用三个线程依次生成像 123123123 这样的输出,您可以打印 count 变量。

            【讨论】:

              【解决方案11】:

              不好的方法是使用多线程来实现:

              private static AtomicInteger currentThreadNo = new AtomicInteger(0);
                  private static int currentNo = 1;
                  private static final Object lock = new Object();
              

              以上,这些值为static,因此它们对于所有工作对象都保持相同。

              import java.util.concurrent.atomic.AtomicInteger;
              
              public class PrintNumbersUsingNThreads implements Runnable {
              
                  private final int threadNo;
                  private final int totalThreads;
                  private static AtomicInteger currentThreadNo = new AtomicInteger(0);
                  private static int currentNo = 1;
                  private static final Object lock = new Object();
              
              
                  public PrintNumbersUsingNThreads(int threadNo, int totalThreads) {
                      this.threadNo = threadNo;
                      this.totalThreads = totalThreads;
                  }
              
                  @Override
                  public  void run() {
              
              
              
                      while (true) {
                          while (currentThreadNo.get() % totalThreads != threadNo) {
                              try {
              
                                  synchronized (lock) {
                                      lock.wait();
                                  }
                              } catch (InterruptedException e) {
                                  e.printStackTrace();
                              }
                          }
                          System.out.println(Thread.currentThread().getName() + " printing " + currentNo);
                          currentNo++;
              
                          int curr = currentThreadNo.get();
                          if (curr == totalThreads) {
                              currentThreadNo.set(1);
                          } else {
                             currentThreadNo.incrementAndGet();
                          }
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          synchronized (lock) {
                              lock.notifyAll();
                          }
                      }
              
                  }
              
                  public static void main(String[] args) {
                      int totalThreads = 3;
              
                      for(int i = 0; i < totalThreads; i++){
                          new Thread(new PrintNumbersUsingNThreads(i,totalThreads),"thread"+i).start();
                      }
              
                  }
              }
              

              输出:

              thread0 printing 1
              thread1 printing 2
              thread2 printing 3
              thread0 printing 4
              thread1 printing 5
              thread2 printing 6
              thread0 printing 7
              thread1 printing 8
              thread2 printing 9
              thread0 printing 10
              thread1 printing 11
              thread2 printing 12
              thread0 printing 13
              thread1 printing 14
              thread2 printing 15
              thread0 printing 16
              thread1 printing 17
              thread2 printing 18
              

              【讨论】:

                【解决方案12】:

                下面是非常通用的代码。我同意在这种情况下使用多个线程不是一个好习惯

                类 MultipleThreads 实现 Runnable {

                AtomicInteger integer;
                
                int max_val = 100;
                
                int remainder;
                int numofThreads;
                
                public MultipleThreads(AtomicInteger integer, int remainder, int numofThreads) {
                    this.integer = integer;
                    this.remainder = remainder;
                    this.numofThreads = numofThreads;
                }
                
                @Override
                public void run() {
                    while (integer.intValue() <= max_val) {
                        synchronized (integer) {
                
                            while (integer.intValue() % numofThreads != remainder) {
                                try {
                                    integer.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            if (integer.intValue() > max_val)
                                break;
                            System.out.println("printing :" + Thread.currentThread().getName() + " : " + integer.getAndIncrement());
                            integer.notifyAll();
                        }
                    }
                }
                

                }

                公共类线程同步{

                public static void main(String[] args) {
                    AtomicInteger at = new AtomicInteger(1);
                    MultipleThreads th1 = new MultipleThreads(at, 1, 5);
                    MultipleThreads th2 = new MultipleThreads(at, 2, 5);
                    MultipleThreads th3 = new MultipleThreads(at, 3, 5);
                    MultipleThreads th4 = new MultipleThreads(at, 4, 5);
                    MultipleThreads th5 = new MultipleThreads(at, 0, 5);
                
                    new Thread(th1).start();
                    new Thread(th2).start();
                    new Thread(th3).start();
                    new Thread(th4).start();
                    new Thread(th5).start();
                }
                

                }

                【讨论】:

                  【解决方案13】:

                  另外,请确保使用 pthread_cond_broadcast 而不是 phread_cond_signal

                  #include "stdio.h"
                  #include "stdlib.h"
                  #include "pthread.h"
                  
                  pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
                  pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
                  void *functionCount1();
                  void *functionCount2();
                  void *functionCount3();
                  int count = 0;
                  #define COUNT_DONE 10
                  
                  void main()
                  {
                      pthread_t thread1, thread2, thread3;
                      pthread_create( &thread1, NULL, &functionCount1, NULL);
                      pthread_create( &thread2, NULL, &functionCount2, NULL);
                      pthread_create( &thread3, NULL, &functionCount3, NULL);
                      pthread_join( thread1, NULL);
                      pthread_join( thread2, NULL);
                      pthread_join( thread3, NULL);
                      exit(0);
                  }
                  
                  // Let me write what I think
                  // we can;t do he %2 %3 since multiple threads may satisfy the conditions.
                  // count = 0; count % 3 = 0
                  // count = 1; count % 3 = 1
                  // count = 2; count % 3 = 2
                  // count = 3; cooun % 3 = 0
                  
                  
                  // Print odd numbers
                  void *functionCount1()
                  {
                      for(;;) {
                          // Lock mutex and then wait for signal to relase mutex
                          pthread_mutex_lock( &count_mutex );
                          if ( count % 3 == 0 ) {
                              printf("Counter value functionCount1: %d\n",count);
                              count++;
                              pthread_cond_broadcast( &condition_var );
                          } else {
                              pthread_cond_wait( &condition_var, &count_mutex );
                          }
                          if ( count >= COUNT_DONE ) {
                              pthread_mutex_unlock( &count_mutex );
                              return(NULL);
                          }
                          pthread_mutex_unlock( &count_mutex );
                      }
                  }
                  
                  // print even numbers
                  void *functionCount2()
                  {
                      for(;;) {
                          // Lock mutex and then wait for signal to relase mutex
                          pthread_mutex_lock( &count_mutex );
                          if ( count % 3 == 1 ) {
                              printf("Counter value functionCount2: %d\n",count);
                              count++;
                              pthread_cond_broadcast( &condition_var );
                          } else {
                              pthread_cond_wait( &condition_var, &count_mutex );
                          }
                          if( count >= COUNT_DONE ) {
                              pthread_mutex_unlock( &count_mutex );
                              return(NULL);
                          }
                          pthread_mutex_unlock( &count_mutex );
                      }
                  }
                  
                  // print even numbers
                  void *functionCount3()
                  {
                      for(;;) {
                          // Lock mutex and then wait for signal to relase mutex
                          pthread_mutex_lock( &count_mutex );
                          if ( count % 3 == 2 ) {
                              printf("Counter value functionCount3: %d\n",count);
                              count++;
                              pthread_cond_broadcast( &condition_var );
                          } else {
                              pthread_cond_wait( &condition_var, &count_mutex );
                          }
                          if( count >= COUNT_DONE ) {
                              pthread_mutex_unlock( &count_mutex );
                              return(NULL);
                          }
                          pthread_mutex_unlock( &count_mutex );
                      }
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    任意数量线程的通用解决方案-

                    对于 3 线程逻辑 =MIN % 3 != 提醒

                    对于 4 个线程= MIN % 4 != 提醒

                    /代码***/

                    公共类 PrintSequenceRunnable1 实现 Runnable {

                    int reminder;
                    
                    static Object lock=new Object();
                    static int MIN=1;
                    int MAX=20;
                    
                    PrintSequenceRunnable1(int reminder){
                        this.reminder=reminder;
                        
                    }
                    
                    public static void main(String[] args) {
                        
                        Thread t1= new Thread(new PrintSequenceRunnable1(1),"T1");
                        Thread t2= new Thread(new PrintSequenceRunnable1(2),"T2");
                        Thread t3= new Thread(new PrintSequenceRunnable1(0),"T3");
                        t1.start();
                        t2.start();
                        t3.start();
                    }
                    
                    @Override
                    public void run() {
                        
                        synchronized (lock) {
                            while (MIN < MAX - 1) {
                                while (MIN % 3 != reminder) {
                                    try {
                                        lock.wait();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                    
                                System.out.println(Thread.currentThread().getName() + "-" + MIN);
                                MIN++;
                                lock.notifyAll();
                    
                            }
                    
                        }
                        
                        
                    }
                    

                    }

                    /**************************************************** ******************/

                    【讨论】:

                      【解决方案15】:
                      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();
                         }
                      }
                      

                      【讨论】:

                        【解决方案16】:
                        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
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-11-05
                          • 2023-04-09
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-06-07
                          相关资源
                          最近更新 更多