使用信号量从2个线程打印替代输出

时间:2017-05-07 17:46:16

标签: java multithreading

我正在学习信号量和多线程的使用,但有些卡住了。我有两个线程分别打印G和H,我的目标是交替每个线程的输出,以便输出字符串是这样的;

G
H
G
H
G
H

这两个类中的每一个都具有类似于下面的布局

public class ClassA extends Thread implements Runnable{

     Semaphore semaphore = null;
     public ClassA(Semaphore semaphore){

         this.semaphore = semaphore;
     }

     public void run() {

        while(true)
        {
            try{
                semaphore.acquire();
                for(int i=0; i<1000; i++){
                    System.out.println("F");

                }
                Thread.currentThread();
                Thread.sleep(100);
            }catch(Exception e)
            {
                System.out.println(e.toString());
            }
            semaphore.release();
        }

    }

}

下面是我的主要课程

public static void main(String[] args) throws InterruptedException {

    Semaphore semaphore = new Semaphore(1);

    ClassA clasA = new ClassA(semaphore);
    Thread t1 = new Thread(clasA);
    ClassB clasB = new ClassB(semaphore);
    Thread t2 = new Thread(clasB);
    t1.start();
    t2.join();
    t2.start();

我得到的输出与我预期的结果太不一样了。有人可以帮我吗?我滥用了信号量吗?有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

信号量无法帮助您解决此类任务。

据我所知,JVM不承诺线程执行中的任何顺序。这意味着如果你运行多个线程,一个线程可以连续多次执行,并且处理器时间比任何其他线程都多。因此,如果您希望线程以特定顺序执行,那么对于最简单的示例,您可以创建一个静态布尔变量,该变量将为您的线程发挥切换器的作用。使用wait()和notify()方法将是一种更好的方法,而Interface Condition将是我认为最好的方法。

import java.io.IOException;

public class Solution {
    public static boolean order;

    public static void main(String[] args) throws IOException, InterruptedException {
        Thread t1 = new ThreadPrint("G", true);
        Thread t2 = new ThreadPrint("O", false);
        t1.start();
        t2.start();
        t2.join();

        System.out.println("Finish");
    }

}

class ThreadPrint extends Thread {

    private String line;
    private boolean order;

    public ThreadPrint(String line, boolean order) {
        this.line = line;
        this.order = order;
    }

    @Override
    public void run() {
        int z = 0;
        while (true) {
            try {
                for (int i = 0; i < 10; i++) {
                    if (order == Solution.order) {
                        System.out.print(line + " ");
                        Solution.order = !order;
                    }
                }
                sleep(100);
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }
    }
}

BTW可能存在另一个问题,因为System.out通常是一个操作系统缓冲区,您的操作系统可以自己按顺序输出您的消息。

P.S。您不应该继承Thread并同时实现Runnable

public class ClassA extends Thread implements Runnable{

因为Thread类已经实现了Runnable。您只能选择一种更适合您目的的方式。

你应该开始一个线程然后加入它而不是相反。

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