简体   繁体   English

3 线程按顺序打印数字

[英]3 Threads Printing numbers in sequence

I am trying to write a simple code to print numbers in sequence.我正在尝试编写一个简单的代码来按顺序打印数字。 Scenario is like场景就像

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

Here is the这里是

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

       }

   }

But just after 2nd thread runs and prints the number 2, all thread get into wait stage and nothing gets printed.但是就在第二个线程运行并打印数字 2 之后,所有线程都进入等待阶段并且没有打印任何内容。 I am not sure where I am doing wrong.我不确定我在哪里做错了。 Any help would be greatly appreciated.任何帮助将不胜感激。

  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 program gives output上面的程序给出了输出

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

Well, the problem is that modulo 3 % 3 is 0 .好吧,问题是模3 % 30 Change your threadId s to 0..2 instead of 1..3 and hopefully it should work.将您的threadId更改为0..2而不是1..3 ,希望它应该可以工作。

Though this is a bad way for using threads, if we still want it a generic solution can be to have a worker thread which will store its id:虽然这是使用线程的坏方法,但如果我们仍然想要它,一个通用的解决方案可以是拥有一个工作线程来存储它的 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;
    }
}

The ResourceLock class would store flag and max threads count: ResourceLock类将存储标志和最大线程数:

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

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

And then main class can use it as below:然后主类可以使用它如下:

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

Here after a certain delay we may like to stop the count and the method shutdown in worker provides this provision.在这里,经过一定的延迟后,我们可能希望停止计数,并且 worker 中的方法 shutdown 提供了此功能。

Below code uses the logic of notifying the next thread to print the number and then incrementing it by 1 and then again notifying the next thread and then go in wait state till some thread notifies it.下面的代码使用通知下一个线程打印数字然后将其增加1然后再次通知下一个线程然后进入等待状态直到某个线程通知它的逻辑。 Eg.例如。 T1 first prints the value and then makes boolean "second" true for T2 to print the next number. T1 首先打印该值,然后使布尔值“秒”为真,以便 T2 打印下一个数字。 T2 after printing the number makes boolean "third" true for T3.打印数字后的 T2 使 T3 的布尔值“第三”为真。 T3 does the same thing by making boolean "first" true for T1 to print the next number. T3 通过为 T1 设置布尔值“first”为真来打印下一个数字来做同样的事情。

T1 -> T2 -> T3 -> T1 -> T2 -> T3 -> ........ and so on. 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++);
  }

How about this?这个怎么样?

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

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

    }


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

} }

The ThreadSynchronization class can be used to print numbers between 'n' no. ThreadSynchronization 类可用于打印“n”号之间的数字。 of threads in sequence.线程的顺序。 The logic is to create a common object between each of the consecutive threads and use 'wait', 'notify' to print the numbers in sequence.逻辑是在每个连续线程之间创建一个公共对象,并使用“等待”、“通知”来按顺序打印数字。 Note: Last thread will share an object with the first thread.注意:最后一个线程将与第一个线程共享一个对象。

You can change the 'maxThreads' value to increase or decrease the number of thread in the program before running it.您可以在运行程序之前更改“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();
        }
    }
}

I have tried it below simple way to print in sequence using three threads and it is working well.我已经尝试过使用三个线程按顺序打印的简单方法,它运行良好。

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

    }
}

You can print count variable instead if you want to generate output like 123123123 in sequence using three threads.如果您想使用三个线程按顺序生成像 123123123 这样的输出,则可以打印计数变量。

Bad way to do but ask is to implement using multiple threads:不好的方法是使用多个线程来实现:

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

Above, these values are static so that they remain same for all the worker objects.上面,这些值是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();
        }

    }
}

output:输出:

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

Below is very generic code.下面是非常通用的代码。 i agree it is not good practice to use multiple threads for such cases我同意在这种情况下使用多个线程不是一个好习惯

class MultipleThreads implements Runnable {类 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 class ThreadSynchronization {公共类 ThreadSynchronization {

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

} }

Also, make sure to use pthread_cond_broadcast instead of phread_cond_signal另外,请确保使用 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 );
    }
}

A general solution for any number of Threads-任意数量线程的通用解决方案-

for 3 thread logic =MIN % 3 != reminder对于 3 线程逻辑 =MIN % 3 != 提醒

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

public class PrintSequenceRunnable1 implements 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();

            }
        }   
    }
}

Here is my solution.这是我的解决方案。 It is pretty simple and easy to understand.这非常简单易懂。 It will help if you are using static variables...如果您使用静态变量,它将有所帮助...

Note that using a lock object is crucial as I tried initially with the this keyword(ex: synchronized(this) ), but it was not been synchronized among all threads.请注意,使用锁定对象至关重要,因为我最初尝试使用this关键字(例如: synchronized(this) ),但它并未在所有线程之间同步。

public class Assignment_Three_Threads {
    public static int TotalNumberOfThreads = 3;

    public static void main(String[] args) {

        multiThread t1 = new multiThread(1);
        multiThread t2 = new multiThread(2);
        multiThread t3 = new multiThread(3);

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

    class multiThread extends  Thread{

    int k=2;
    private  int threadId ;
    private static int threadIdToRun = 1;
    private static final Object lock = new Object();
    multiThread(int id)
    {
        super();
        this.threadId = id;
    }

    @Override
    public void run() {

                for (int i = 0; i < k; i++) {

                     synchronized (lock) {

                        while(true) {
                            if (this.threadId != threadIdToRun) {
                                try {
                                    lock.wait();
                                } catch (InterruptedException e) {
                                    throw new RuntimeException(e);
                                }
                            }

                            if (this.threadId == threadIdToRun) {
                                System.out.println("Thread : " + this.threadId);
                                threadIdToRun =
                                        (threadIdToRun % Assignment_Three_Threads.TotalNumberOfThreads) + 1;

    //                             System.out.println("Next Thread to be printed " + threadIdToRun);
                                lock.notifyAll();
                                break;
                            }
                        }
                     }

                }


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

        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM