简体   繁体   中英

Displaying threads alternatively in JAVA

I want to display this two threads alternatively like that:

  • Thread 1
  • Thread 0
  • Thread 1
  • Thread 0...

That's the basic code from where I started, I tried with wait() notify() Methods but I couldn't get the result wanted.

class Task extends Thread {
    @Override
    public void run() {
        try {
            for(int i = 0; i<10; i++){

                double dure = Math.random()*200 ;
                sleep((long) dure);
                System.out.println(Thread.currentThread().getName());
            }
        } catch (Exception e) {
        }
    }
}

public class App {
    public static void main(String[] args) {

        Task t1 = new Task() ;
        Task t2 = new Task() ;

        t1.start();
        t2.start();


        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
        }
        
        
    }
    
} ```


 

I see two solutions:

  1. Busy Wait

Each thread wait before printing. And release when the condition is true. I used AtomicInteger for indexToPrint .

This solution works with undefined number of thread.

import java.util.concurrent.atomic.AtomicInteger;

class Task extends Thread {
    
    final static private AtomicInteger indexToPrint = new AtomicInteger(0);

    static private int threadNumber = 0;

    final private int index;

    /**
     *
     */
    public Task() {
        index = threadNumber++;
    }


    private int nextIndex() {
        return (index + 1) % threadNumber;
    }

    @Override
    public void run() {

        try {    

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

                double dure = Math.random()*200 ;
                sleep((long) dure);

                while (indexToPrint.get() != index) {
                    sleep((long) 10);
                }
                indexToPrint.set(nextIndex());
                
                System.out.println(Thread.currentThread().getName());
                
            }
        } catch (Exception e) {}
    }
}
  1. wait and notify

A bit more complex to understand but no useless CPU use. You can find a good documentation here .

The code is based on the previous one. With same use of indexToPrint .

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

class Task extends Thread {

    static private final AtomicInteger indexToPrint = new AtomicInteger(0);

    static private int threadNumber = 0;

    final private int index;

    final private static ArrayList<Task> tasks = new ArrayList<>();

    /**
     *
     */
    public Task() {
        index = threadNumber++;
        tasks.add(this);
    }


    private int nextIndex() {
        return (index + 1) % threadNumber;
    }

    @Override
    public void run() {

        try {

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

                double dure = Math.random()*200 ;
                sleep((long) dure);

                synchronized (indexToPrint) {
                    while (indexToPrint.get() != index) {
                        indexToPrint.wait();
                    }
                    indexToPrint.set(nextIndex());
                    System.out.println(Thread.currentThread().getName());
                    indexToPrint.notifyAll();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The random sleep time can cause the unexpected result also within the main method making the main thread sleep between the start of Thread1 and Thread2 can help you to know who is the first thread that will start the print task, after that you should give the right sleep time inside the task to give the Threads the possibility to prints alternatively.

class Task extends Thread {
@Override
public void run() {
    try {
        for(int i = 0; i<10; i++){
            sleep(2000);
            System.out.println(Thread.currentThread().getName());
        }
    } catch (Exception e) {
    }
}
}

public class App {
public static void main(String[] args) {

    Task t1 = new Task() ;
    Task t2 = new Task() ;

    t1.start();
   try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
    t2.start();

}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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