简体   繁体   English

在 JAVA 中交替显示线程

[英]Displaying threads alternatively in JAVA

I want to display this two threads alternatively like that:我想像这样交替显示这两个线程:

  • Thread 1线程 1
  • Thread 0线程 0
  • Thread 1线程 1
  • Thread 0...线程 0...

That's the basic code from where I started, I tried with wait() notify() Methods but I couldn't get the result wanted.这是我开始的基本代码,我尝试了wait() notify()方法,但我无法得到想要的结果。

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 .我将AtomicInteger用于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.理解起来有点复杂,但没有无用的 CPU 使用。 You can find a good documentation here .你可以在这里找到一个很好的文档

The code is based on the previous one.该代码基于上一个。 With same use of indexToPrint .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.随机休眠时间也会导致意外结果在main方法中使主线程在Thread1和Thread2启动之间休眠可以帮助你知道谁是第一个启动打印任务的线程,之后你应该给权任务内的睡眠时间,以使线程可以交替打印。

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

}
}

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

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