java - 使用信号量打印 2 个线程的替代输出

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

我得到的输出与我的预期结果相差太大。有人可以帮我吗?我是否滥用了信号量?有什么帮助吗?

最佳答案

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

据我所知,JVM不 promise 线程执行的任何顺序。这意味着如果您运行多个线程,则一个线程可以连续执行多次,并且比任何其他线程拥有更多的处理器时间。因此,如果您希望线程按特定顺序执行,您可以举个最简单的例子,创建一个静态 boolean 变量,它将扮演线程切换器的角色。使用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());
            }
        }
    }
}

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

附注你不应该继承Thread并同时实现Runnable

public class ClassA extends Thread implements Runnable{

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

您应该启动一个线程然后加入它,反之亦然。

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

关于java - 使用信号量打印 2 个线程的替代输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43834700/

相关文章:

java - 单例的 OnSaveInstanceState

java - 提高 HTTPClient 连接 Android 的速度

android - 在Android中还有什么被认为是繁重的任务?

C# 手动锁定/解锁

java - Java 中 Do-While 循环的 ExecutorService

c++ - 等待 QTcpSocket 数据时阻止 GUI

java - java编码中swing中的数组索引越界错误

java - 如何订购多边形的点?

java - 从 OSGI bundle 调用 JDBC 和 UCP 连接

java - 如何防止主线程执行下一行,直到最后一行完全执行