Java Thread loops running sequentially - java

public class Meh {
public static void main(String[] args) {
Thread th2=new Thread() {
public void run(){
for (int i=0;i<=10;i++) {
System.out.println("No 2 "+i);
}
}
};
Thread th1=new Thread() {
public void run(){
for (int i=0;i<=10;i++) {
System.out.println("No 1 "+i);
}
}
};
for (int i=0;i<=10;i++) {
System.out.println("main "+i);
}
th1.start();
th2.start();
}
}
Why are my loops running sequentially?The three loops get interchanged but inside the loop they run sequentially. I can't figure it out why? I am a beginner in java.

Why does your code run sequentially
Your code has 3 parts, which I have colour coded as follows:
Red
Thread th1 = new Thread() {
public void run() {
for (int i = 0; i <= 10; i++) {
System.out.println("No 1 " + i);
}
}
};
...
for (int i=0;i<=10;i++) {
System.out.println("main "+i);
}
th1.start();
th2.start();
Green
Thread th1 = new Thread() {
public void run() {
for (int i = 0; i <= 10; i++) {
System.out.println("No 1 " + i);
}
}
};
Blue
Thread th2 = new Thread() {
public void run() {
for (int i = 0; i <= 10; i++) {
System.out.println("No 2 " + i);
}
}
};
As you can see, green and blue will mix together, but they will not run out of their own order, (No 1 6 will never happen before No 1 5, but could be anywhere compared to the No 2 items).

Perhaps you have misunderstood what a Thread actually does. Putting loops inside a Runnable doesn't automatically parallelize them for you. It just runs the code sequentially but in a separate thread. I'm guessing what you really want is the following:
Thread[] threads = new Thread[11];
for (int i = 0; i <= 10; i++) {
threads[i] = new Thread(() -> System.out.println(Thread.currentThread().getName()));
threads[i].setName("Thread #"+i);
}
for (Thread thread : threads) {
thread.start();
}

Related

Print numbers 1,2,3 using thread1 and 4,5,6 using thread2, and 7,8,9 using thread3 and again 10,11,12 using thread1

I am trying a write a simple program with wait and notify in which I will create 3 threads.
The first thread should print 1, 2, 3.
The second thread should print 4, 5, 6.
The third thread should print 7, 8, 9.
After that, the first thread should print 10, 11, 12 and so on.
Below is a sample code for the same exercise, but I am unable to print the desired output.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo){
this.threadNo= threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
if(threadNoToRun != threadNo)
obj.wait();
else{
for(int i = 1 ; i < 4 ; i++){
if(threadNoToRun == threadNo){
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
if(threadNoToRun == 1){
threadNoToRun = 2;
}
else if(threadNoToRun == 2){
threadNoToRun = 3;
}
else if(threadNoToRun == 3){
threadNoToRun = 1;
}
}
}
obj.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main (String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}
The output looks like:
1 counter value is 1
1 counter value is 2
1 counter value is 3
2 counter value is 4
2 counter value is 5
2 counter value is 6
Here, it was just a few changes.
Nonetheless, I have to point out that this kind of concurrency does NOT increase computation speed. Only one thread is alive at all times.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo) {
this.threadNo = threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
while (counter < 100) {
if (threadNoToRun != threadNo)
obj.wait();
else {
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
if (threadNoToRun == 1) {
threadNoToRun = 2;
} else if (threadNoToRun == 2) {
threadNoToRun = 3;
} else if (threadNoToRun == 3) {
threadNoToRun = 1;
}
obj.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}

Why the thread will be blocked when it executes the code "while (Thread.activeCount() > 1) "?

Following code exists in chapter 13 of "UnderStanding the JVM Advanced Features and Best Practices, second Edition".
But when the thread execute " while (Thread.activeCount() > 1)", it will be blocked and nothing will be printed.
public class Code_12_1 {
public static AtomicInteger race = new AtomicInteger(0);
public static void increment(){
race.incrementAndGet();
}
private static final int THREADS_COUNT = 20;
public static void main(String[] args) throws Exception{
Thread[] threads = new Thread[THREADS_COUNT];
for (int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(new Runnable() {
#Override
public void run() {
for (int j = 0; j < 10000; j++) {
increment();
}
}
});
threads[i].start();
}
while (Thread.activeCount() > 1)
Thread.yield();
System.out.println(race);
}
}
But when I change "while (Thread.activeCount() > 1)" to "while (Thread.activeCount()>2)" the thread can execute correctly and output the answer 200000.
So, why thread will be blocked when it executes "while (Thread.activeCount() > 1)"?
I have figured it out. I ran your code and it turns out there is already another Thread running besides the Main thread initially(in the current ThreadGroup), even before you all other threads. So, the following print statement gave me a count of 2(see the initialCount):
public static void main(String[] args) throws Exception{
Thread[] threads = new Thread[THREADS_COUNT];
int initialCount = Thread.activeCount();
System.out.println("Initial count: " + initialCount);
for (int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(new Runnable() {
#Override
public void run() {
for (int j = 0; j < 10000; j++) {
increment();
}
}
});
threads[i].start();
}
while (Thread.activeCount() > 1){
System.out.println(race);
System.out.println(Thread.activeCount());
Thread.yield();
}
}
So, what you have to do is:
while (Thread.activeCount() > initialCount){
Thread.yield();
}
And, it will work as expected.
Reasoning: It is blocked because all your Threads finish executing after you start them and then you have this additional thread remaining that never makes you exit the while loop.
If you insert a print statement before Thread.yield(), you get an output like,
200000
200000
200000
200000
200000
200000
...
...
This supports the reasoning that all the Threads have finished and just 2 are left that keep the loop running.

How to make parallel programming with input values in java

I implement a recommendation algorithm in Java program.
However, I have serious problems. The dataset is too large and it's computation is too slow. So, I need to do parallel programming in Java.
For example,
for (int i=0; i < 10000000 ; i++) { ~~~ }
I want to split this sentences such as
process 1: for (int i=0; i < 10000 ; i++)
process 2: for (int i=10001; i < 20000 ; i++)
process 3: for (int i=20001; i < 30000 ; i++)
...
I know similar methods in Python. How to do parallel programming in Java?
Hope this will help you.
public class MyRunnable implements Runnable {
private final long countUntil;
MyRunnable(long countUntil) {
this.countUntil = countUntil;
}
#Override
public void run() {
long sum = 0;
for (long i = 1; i < countUntil; i++) {
sum += i;
}
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args) {
// We will store the threads so that we can check if they are done
List<Thread> threads = new ArrayList<Thread>();
// We will create 500 threads
for (int i = 0; i < 500; i++) {
Runnable task = new MyRunnable(10000000L + i);
Thread worker = new Thread(task);
// We can set the name of the thread
worker.setName(String.valueOf(i));
// Start the thread, never call method run() direct
worker.start();
// Remember the thread for later usage
threads.add(worker);
}
int running = 0;
do {
running = 0;
for (Thread thread : threads) {
if (thread.isAlive()) {
running++;
}
}
System.out.println("We have " + running + " running threads. ");
} while (running > 0);
}
}
i got it from here

How to remove manually created pauses in Main-thread?

Problem description:
We have a given matrix randomly filled with digits and have to create separate threads for each row of the matrix that count how many times the digits encounter in that row.
Without these sleeps in the main thread, it's not working correctly..
Here's my solution.
Also it's following here:
public class TestingMatrixThreads {
public static void main(String[] arr) throws InterruptedException {
int[][] a = new int[67][6];
// class.Count works with class.Matrix, that's why I've made it this way
Matrix m = new Matrix(a);
m.start();
Thread.sleep(1000); // Here comes the BIG question -> how to avoid these
// manually created pauses
Count c;
Thread t;
// Creating new threads for each row of the matrix
for (int i = 0; i < Matrix.matr.length; i++) {
c = new Count(i);
t = new Thread(c);
t.start();
}
//Again - the same question
System.out.println("Main - Sleep!");
Thread.sleep(50);
System.out.println("\t\t\t\t\tMain - Alive!");
int sum = 0;
for (int i = 0; i < Count.encounters.length; i++) {
System.out.println(i + "->" + Count.encounters[i]);
sum += Count.encounters[i];
}
System.out.println("Total numbers of digits: " + sum);
}
}
class Count implements Runnable {
int row;
public static int[] encounters = new int[10]; // here I store the number of each digit's(array's index) encounters
public Count(int row) {
this.row = row;
}
public synchronized static void increment(int number) {
encounters[number]++;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + ", searching in row " + row + " STARTED");
for (int col = 0; col < Matrix.matr[0].length; col++) {
increment(Matrix.matr[row][col]);
}
try {
Thread.sleep(1); // If it's missing threads are starting and stopping consequently
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + " stopped!");
}
}
class Matrix extends Thread {
static int[][] matr;
public Matrix(int[][] matr) {
Matrix.matr = matr;
}
#Override
public void run() {
//print();
fill();
System.out.println("matrix filled");
print();
}
public static void fill() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
matr[i][j] = (int) (Math.random() * 10);
}
}
}
public static void print() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
System.out.print(matr[i][j] + " ");
}
System.out.println();
}
}
}
P.S. I'm sorry if this question is too stupid for you to answer, but I'm a newbie in Java programming, as well as it's my very first post in stackoverflow, so please excuse me for the bad formatting, too :)
Thank you in advance!
Change the Thread.sleep by m.join()
Doing this will make the main thread wait for the other to complete its work and then it will continu its execution.
Cheers
To answer your main question:
Thread.join();
For example:
public static void main(String[] args) throws Exception {
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Do stuff");
}
});
t.start();
t.join();
}
The start call, as you know, kicks off the other Thread and runs the Runnable. The join call then waits for that started thread to finish.
A more advanced way to deal with multiple threads is with an ExecutorService. This detaches the threads themselves from the tasks they do. You can have a pool of n threads and m > n tasks.
Example:
public static void main(String[] args) throws Exception {
final class PrintMe implements Callable<Void> {
final String toPrint;
public PrintMe(final String toPrint) {
this.toPrint = toPrint;
}
#Override
public Void call() throws Exception {
System.out.println(toPrint);
return null;
}
}
final List<Callable<Void>> callables = new LinkedList<>();
for (int i = 0; i < 10; ++i) {
callables.add(new PrintMe("I am " + i));
}
final ExecutorService es = Executors.newFixedThreadPool(4);
es.invokeAll(callables);
es.shutdown();
es.awaitTermination(1, TimeUnit.DAYS);
}
Here we have 4 threads and 10 tasks.
If you go down this route you probably need to look into the Future API to so that you can check whether the tasks completed successfully. You can also return a value from the task; in your case a Callable<Integer> would seem to be appropriate so that you can return the result of your calculation from the call method and gather up the results from the Future.
As other Answers have stated, you can do this simply using join; e.g.
Matrix m = new Matrix(a);
m.start();
m.join();
However, I just want to note that if you do that, you are not going to get any parallelism from the Matrix thread. You would be better of doing this:
Matrix m = new Matrix(a);
m.run();
i.e. executing the run() method on the main thread. You might get some parallelism by passing m to each "counter" thread, and having them all join the Matrix thread ... but I doubt that it will be worthwhile.
Frankly, I'd be surprised if you get a worthwhile speedup for any of the multi-threading you are trying here:
If the matrix is small, the overheads of creating the threads will dominate.
If the matrix is large, you are liable to run into memory contention issues.
The initialization phase takes O(N^2) computations compared with the parallelized 2nd phase that has N threads doing O(N) computations. Even if you can get a decent speedup in the 2nd phase, the 1st phase is likely to dominate.

Ending threads in java correctly

I have a problem with Threads in Java.
I would like to write a program where there is Class Main which has ArrayList of Threads of some class (Class Task) which just writes a letter and the number. Object Main just wakes one Thread from ArrayList and let it to do something while the same object(Main) sleeps another one.
But there is one problem even if I change the Main.ACTIVE to false it does not end all of the Threads some stay on, and it's random, I just would like to make them end and write:
I am saying goodbay + character - sth like that
public class Main extends Thread {
ArrayList<Thread> threads;
static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(50);
monitor.wait();
} catch(Exception e){
e.printStackTrace();}
}
System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
And the Task Class
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}
I would recommend that you look at the more modern concurrency classes in java.util.concurrent package, especially ExecutorService. And read "Java Concurrency In Practice."
Your problem is for starters that ACTIVE should be marked as volatile. Any variable that is shared by multiple threads needs to somehow be synchronized or marked as volatile so that it will have a memory barrier around its reading and writing.
Another thing you can do from a boolean standpoint is to use the AtomicBoolean class instead of a volatile boolean.
Instead of a static volatile boolean, you might instead consider to have a volatile boolean for each Task object so that Main has more fine grained control over the individual tasks and you are using a static "global" variable. You could even add a task.shutdown() method to set the active flag.
Lastly, as #duffmo mentioned, you should always consider using one of the thread-pools ExecutorService if you always just want to have one thread running. Something like Executors.newFixedThreadPool(1). But I can't quite tell if you only want one thread all of the time. If you used an ExecutorService then main would just do:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i <= 5; i++) {
// the monitor would not be needed
threadPool.submit(new Task(i + 65));
}
threadPool.shutdown();
for (Future future : futures) {
// this waits for the working task to finish
future.get();
}
But if you need your background task to stop and start like it is currently doing with the monitor then this model might not work.
Now naswer is
0A, 0B, 0C, 0D, 0E, 0F, 1A, 1B, 1C, 1D, 1E, 1F, WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
LAST COMMAND IN MAIN
I added sleep after starting threads
import java.util.ArrayList;
public class Main extends Thread {
ArrayList<Thread> threads;
volatile static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}
// System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(500);
monitor.wait();}catch(Exception e){e.printStackTrace();}
}
// System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
and the TASK
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
// System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
// System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}

Categories