Printing 1 to 100 using 10 threads in java

I'm new to muti-threading, and I had a question to print from 1 to 100 using 10 threads in Java with a limit below.

  • The subject t1 should print:

    1, 11, 21, 31, ... 91

    t2 should print:

    2, 12, 22, 32, ... 92

    also

    t10 should print:

    10, 20, 30, ... 100

  • The end result should be

    1 2 3 .. 100

I tried this, but it throws the following exception in all 10 threads:

 java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at thread.run(MyThread.java:58) at java.lang.Thread.run(Unknown Source) 

Please let me know how I can solve this problem.

 public class MyThread { /** * @param args */ public static void main(String[] args) { thread.setSequence(); for(int i = 1; i <= 10; i++) { Thread t = new Thread(new thread(i)); t.setName(i + ""); t.start(); } } } class thread implements Runnable { private static HashMap< String, String> sequence = new HashMap<String, String>(); public static final Object lock = new Object(); public static String turn = "1"; private int startValue = 0; private AtomicInteger counter = new AtomicInteger(1); public thread(int startValue){ this.startValue = startValue; } @Override public void run() { while (!counter.equals(10)){ synchronized (lock) { if(Thread.currentThread().getName().equals(turn)){ System.out.print(startValue + " "); startValue += 10; counter.incrementAndGet(); turn = getNextTurn(turn); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else{ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); } } } public static void setSequence(){ for (int i = 1; i <= 10; i++) if (i == 10) sequence.put(i + "", 1 + ""); else sequence.put(i + "", (i + 1) + ""); } public static String getNextTurn(String currentTurn){ return sequence.get(currentTurn); } } 
+6
source share
10 answers

The easiest way is to have a mutable variable from which each stream reads and updates in accordance with its rotation, otherwise it simply waits for its rotation. When counter is 100 , you stop all threads to start, breaking the outer loop.

 class MyRunnable implements Runnable { private static final int LIMIT = 20; private static volatile int counter = 0; private int id; public MyRunnable(int id) { this.id = id; } @Override public void run() { outer: while(counter < LIMIT) { while (counter % NB_THREADS != id) { if(counter == LIMIT) break outer; } System.out.println("Thread "+Thread.currentThread().getName()+ " printed " + counter); counter += 1; } } } 

Given a LIMIT of 20 and 10 threads, it produces:

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

Of course, this is a very poor use of multithreading, because each thread is waiting in line for printing and increasing the counter.

Multithreading works well when threads can run independently for a relatively long time, and then can sometimes be found to compare or combine their results, if necessary.

For example, in the fork-join model, each thread performs its task independently, then their results are combined to obtain the final result, for example, in a merge sort, for example. But this assumes that the task can be easily parallelized into independent sub-tasks, which is not the case here, because your final result should be consecutive numbers.

So here a simple cycle will be much more efficient, but I can understand it for training purposes.

+6
source

The error is caused due to the wait call not on the corresponding object. wait() must be called on the object on which the lock was received, and is implied by the synchronized .

+2
source

Here is the solution to the problem. The current thread gets a lock, and we decide whether the thread can execute (print the number here). If so, do the operation and report all the threads that they can try now. Else waits until other threads notify him.

 public class MyThread extends Thread{ //define the Total No.Of Threads needed public static final int TOTAL_THREADS = 10; public final static Object obj = new Object(); int threadNo; static volatile int counter = 1; public MyThread(int threadNo){ this.threadNo= threadNo; } @Override public void run(){ //in a synchronized block to acquire lock synchronized (obj) { while(counter<=100){ /* * counter==threadNo => To print the initial numbers till TOTAL_THREADS * counter%TOTAL_THREADS == threadNo => eg 11%10 = 1 -> 1 will print this, 12%10 = 2 .. * (counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo) => 10%10 will be 0, * and this must be printed by 10 th thread only, ie the highest thread. */ if(counter == threadNo || (counter%TOTAL_THREADS == threadNo) || ((counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo))){ //Display the output as desired System.out.println(this.threadNo+" printing"+" "+counter++); //notify obj.notifyAll(); }else{ //current thread not eligible for printing the current counter value, so wait till its notified try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public static void main (String args[]) { /* * Creating as many threads as needed. */ for(int i = 1; i<=TOTAL_THREADS;i++){ MyThread th = new MyThread(i); th.start(); } } 

}

The output will be
1 seal 1,
2 seal 2,
3 seal 3,
4 seal 4,
5 print 5,
6 seal 6,
7 stamp 7,
8 seal 8,
9 stamp 9,
10 stamp 10,
1 seal 11,
2 seal 12,
3 seal 13,
4 seal 14,
...
7 seal 97,
8 seal 98,
9 seal 99,
10 stamp 100

+2
source

Hope this helps =) Took me an hour to do this.

 package com.xxxx.simpleapp; import java.util.ArrayList; import java.util.List; public class TenThreads { public int currentTaskValue = 1; public static void main(String[] args) { TenThreads monitor = new TenThreads(); List<ModThread> list = new ArrayList(); for (int i = 0; i < 10; i++) { ModThread modThread = new ModThread(i, monitor); list.add(modThread); } for (ModThread a : list) { a.start(); } } } class ModThread extends Thread { private int modValue; private TenThreads monitor; public ModThread(int modValue, TenThreads monitor) { this.modValue = modValue; this.monitor = monitor; } @Override public void run() { synchronized (monitor) { try { while (true) { while (monitor.currentTaskValue % 10 != modValue) { monitor.wait(); } if (monitor.currentTaskValue == 101) { break; } System.out.println(Thread.currentThread().getName() + " : " + monitor.currentTaskValue + " ,"); monitor.currentTaskValue = monitor.currentTaskValue + 1; monitor.notifyAll(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

Output

 Thread-1 : 1 , Thread-2 : 2 , Thread-3 : 3 , Thread-4 : 4 , Thread-5 : 5 , Thread-6 : 6 , Thread-7 : 7 , Thread-8 : 8 , Thread-9 : 9 , ...... ..... ... Thread-4 : 94 , Thread-5 : 95 , Thread-6 : 96 , Thread-7 : 97 , Thread-8 : 98 , Thread-9 : 99 , Thread-0 : 100 , 

The documentation is intentionally not taken into account to understand this, there are minor errors!

+1
source

Well, I don’t have a code ... but the prospect seems that there are 100 tasks that each of the increments should be performed by 1. Thus, there can be a ThreadPool of 10 threads, and these threads increase the total value of the counter ... You should only consider that Thread thread threads must sequentially perform their tasks one by one and thread sequence for 10 must be supported ...

+1
source
 public class BigSequence { public static void main(String[] args) { BigPrintNum p = new BigPrintNum(); int max = 20; int no_threads = 11; for(int i=0;i<no_threads;i++){ boolean b[] = new boolean[no_threads]; b[i] = true; Thread t = new Thread(new BigPrint(p, max, b,no_threads)); t.start(); } } } class BigPrint implements Runnable { int num=0; BigPrintNum p; int max; int no_threads; boolean b[]; public BigPrint(BigPrintNum p,int max,boolean b[],int no_threads){ this.p = p; this.max = max; this.b = b; this.no_threads = no_threads; } @Override public void run() { int n = 0; for(int i=0;i<no_threads;i++){ if(b[i] == true){ n = i; num = i; } } while(num<=max){ p.print(num, n, no_threads); num += no_threads; } } } class BigPrintNum { int turn = 0; public synchronized void print(int n,int i,int no_threads){ while(this.turn != i){ try{ wait(); }catch(InterruptedException e){ e.printStackTrace(); } } System.out.println(i + "th seq = " + n); this.turn = (i+1)%no_threads; notifyAll(); } } 

Its common where we can use any number of threads and use any maximum value.

0
source

public class ThreadSequence {

 public static int totalThread; public static void main(String[] args) { MyLock myLock = new MyLock(); totalThread = 10; for(int i=1;i<=totalThread;i++) { MyThread myThread = new MyThread(i,myLock); myThread.start(); } } 

}

class MyLock {

 public int counter = 0; 

}

Class mythread

class MyThread extends Thread {

 public MyLock lock; public int no; public MyThread(int no,MyLock lock) { super("My Thread No "+no); this.no = no; this.lock = lock; } public void run() { synchronized (lock) { while(true) { while(lock.counter%ThreadSequence.totalThread !=(this.no-1)) { try { if(lock.counter > 99) { break; } lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if(lock.counter > 99) { break; } System.out.println("Current Thread "+Thread.currentThread().currentThread()+" --- Current Count "+(lock.counter+1)); lock.counter = lock.counter +1 ; lock.notifyAll(); } } } 

}

0
source

The easiest way to do this is to keep a shared resource for everyone. Keep a list, and each stream will be inserted into the list, at the end you can sort and print. If you want them to do this on your order, it will not be very effective because you will not need 10 threads to do this.

This way it will be faster and will use 10 threads to do some work, but when it all ends, you still need to do some work.

-1
source
 public class PrintNumbersbyThreads implements Runnable { private int i; public PrintNumbersbyThreads(int i) { this.i = i; } public static void main(String[] args) { PrintNumbersbyThreads p = new PrintNumbersbyThreads(1); PrintNumbersbyThreads p2 = new PrintNumbersbyThreads(2); PrintNumbersbyThreads p3 = new PrintNumbersbyThreads(3); Thread t1 = new Thread(p, "t1"); Thread t2 = new Thread(p2, "t2"); Thread t3 = new Thread(p3, "t3"); t1.start(); try { t1.join(); t2.start(); t2.join(); t3.start(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { System.out.println("\n" + Thread.currentThread().getName() + " prints "); for (int j = 0; j < 10; j++) { System.out.print(i + " "); i = i + 10; } } } 

Written Code Sample 3 Themes and Exit

t1 Prints:

1 11 21 31 41 51 61 71 71 81 91

t2 Prints:

2 12 22 32 42 52 52 62 72 82 92

t3 Prints:

3 13 23 33 43 53 53 63 73 83 93

Hope this is what you are looking for?

-1
source

I wrote one common code that will take a number as long as you want to print, and the number of threads that will be used.

 public class ThreadedPrinting { private Object locks[]; private static class Printer extends Thread { int curVal; int endVal; Object myLock; Object nextLock; int step; public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){ this.curVal = startFrom; this.endVal = endVal; this.step = step; this.myLock = myLock; this.nextLock = nextLock; this.step = step; } @Override public void run(){ synchronized(myLock) { while (curVal <= endVal) { try { myLock.wait(); System.out.println(curVal); curVal += step; } catch(InterruptedException e) {} synchronized(nextLock) { nextLock.notify(); } } } synchronized(nextLock) { nextLock.notify(); /// this ensures all worker threads exiting at the end } } } // Printer public ThreadedPrinting(int maxNum, int threads) { locks = new Object[threads]; int i; for(i = 0; i < threads; ++i) locks[i] = new Object(); for(i = 0; i < threads -1 ; ++i) { Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]); curPrinter.start(); } Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]); lastPrinter.start(); } public void start() { synchronized (locks[0]) { locks[0].notify(); } } public static void main(String[] args) { ThreadedPrinting printer = new ThreadedPrinting(1000,7); printer.start(); } } 

The same problem can be solved with the help of Phaser, but the order is not restrictive, but it will be in a circular mode. I suggested a solution for a similar problem here .

-1
source

Source: https://habr.com/ru/post/986481/


All Articles