在java中使用两个线程多次打印“hello”和“world”

x9ybnkn6  于 2021-06-30  发布在  Java
关注(0)|答案(7)|浏览(400)

假设一个线程打印“hello”,另一个线程打印“world”。我曾经成功地做过一次,如下:包线程;

public class InterThread {

    public static void main(String[] args) {
        MyThread mt=new MyThread();
        mt.start();
        synchronized(mt){
            System.out.println("Hello");
            try {
                mt.wait();
                i++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

}

class MyThread extends Thread{

    public void run(){
        synchronized(this){
        System.out.println("World!");
        notify();
        }
    }
}

我怎么做多次打印,比如说5次?我试着在同步块上循环,但是没有用。

5lwkijsr

5lwkijsr1#

有两个线程,它们都有自己的数据(“hello”和true对ht,“world”和false对wt),并共享一个变量objturn。

public class HelloWorldBy2Thread {  
    public static void main(String[] args) {
        PrintHelloWorld hw = new PrintHelloWorld(); 
        HelloThread ht = new HelloThread(hw);
        WorldThread wt = new WorldThread(hw);
        ht.start();
        wt.start();
    }
}
public class HelloThread extends Thread {   
    private PrintHelloWorld phw;
    private String hello;
    public HelloThread(PrintHelloWorld hw) {
        phw = hw;
        hello = "Hello";
    }   
    @Override
    public void run(){
        for(int i=0;i<10;i++)
            phw.print(hello,true);
    }
}
public class WorldThread extends Thread {
    private PrintHelloWorld phw;
    private String world;
    public WorldThread(PrintHelloWorld hw) {
        phw = hw;
        world = "World";
    }
    @Override
    public void run(){
        for(int i=0;i<10;i++)
            phw.print(world,false);
    }
}
public class PrintHelloWorld {  
    private boolean objturn=true;
    public synchronized void print(String str, boolean thturn){
        while(objturn != thturn){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(str+" ");
        objturn = ! thturn;
        notify();               
    }
}
yb3bgrhw

yb3bgrhw2#

这是c:


# include <stdio.h>

# include <pthread.h>

pthread_mutex_t hello_lock, world_lock;

void printhello()
{
    while(1) {
        pthread_mutex_lock(&hello_lock);
        printf("Hello ");
        pthread_mutex_unlock(&world_lock);
    }
}

void printworld()
{
    while(1) {
        pthread_mutex_lock(&world_lock);
        printf("World ");
        pthread_mutex_unlock(&hello_lock);
    }
}

int main()  
{
    pthread_t helloThread, worldThread;

    pthread_create(&helloThread,NULL,(void *)printhello,NULL);
    pthread_create(&helloThread,NULL,(void *)printhello,NULL);

    pthread_join(helloThread);
    pthread_join(worldThread);

    return 0;
}
jqjz2hbq

jqjz2hbq3#

这里的目标是同步线程,以便在一个线程完成时通知另一个线程。如果我必须这样做,它将是两个线程用不同的数据执行相同的代码。每个线程都有自己的数据( "Hello" 以及 true 到t1, "World" 以及 false 到t2),并共享一个变量 turn 加上一个单独的锁对象。

while(/* I need to play*/){
  synchronized(lock){
    if(turn == myturn){
      System.out.println(mymessage);
      turn = !turn; //switch turns
      lock.signal();
     }
     else{
       lock.wait();
     }
  }
}
jaql4c8m

jaql4c8m4#

这里是两个相互依赖的线程,我们需要两个同步对象。它们可能是很多东西中的一个。一个整数,另一个对象;一个布尔值另一个对象;两个目标;信号量等等。同步技术可以是监视器或信号量,但它们必须是两个。
我修改了你的代码,用信号量代替监视器。信号量的工作更加透明。您可以看到获取和释放正在发生。监视器是更高的结构。因此在引擎盖下同步工作。
如果您对以下代码感到满意,那么可以将其转换为使用监视器。

import java.util.concurrent.Semaphore;

    public class MainClass {

        static Semaphore hello = new Semaphore(1);
        static Semaphore world = new Semaphore(0);

        public static void main(String[] args) throws InterruptedException {
            MyThread mt=new MyThread();     
            mt.hello = hello;
            mt.world = world;
            mt.start();

            for (int i=0; i<5; i++) {
                hello.acquire(); //wait for it
                System.out.println("Hello");

                world.release(); //go say world
            }
        }
    }

    class MyThread extends Thread{

        Semaphore hello, world;

        public void run(){
            try {
                for(int i = 0; i<5; i++) {
                    world.acquire(); // wait-for it
                    System.out.println("  World!");

                    hello.release(); // go say hello
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
mitkmikd

mitkmikd5#

在你开始尝试让它工作五次之前,你需要确保它工作一次!
你的代码不能保证总是打印hello world!-在锁定mt之前,主线程可能会被中断(请注意,锁定线程对象通常不是一个好主意)。

MyThread mt=new MyThread();
mt.start();
\\ interrupted here
synchronized(mt){
  ...

一种方法是使用原子布尔值,这种方法可以推广很多次

import java.util.concurrent.atomic.AtomicBoolean;
public class InterThread {

    public static void main(String[] args) {
        int sayThisManyTimes = 5;
        AtomicBoolean saidHello = new AtomicBoolean(false);

        MyThread mt=new MyThread(sayThisManyTimes,saidHello);
        mt.start();

        for(int i=0;i<sayThisManyTimes;i++){
          while(saidHello.get()){} // spin doing nothing!
          System.out.println("Hello ");
          saidHello.set(true);
        }    
    }

}

class MyThread extends Thread{

    private final int sayThisManyTimes;
    private final AtomicBoolean saidHello;
    public MyThread(int say, AtomicBoolean said){
      super("MyThread");
      sayThisManyTimes = say;
      saidHello = said;
    }

    public void run(){
        for(int i=0;i<sayThisManyTimes;i++){
          while(!saidHello.get()){} // spin doing nothing!
          System.out.println("World!");
          saidHello.set(false);
        }
    }
}
ssm49v7z

ssm49v7z6#

public class ThreadSeq {

    Object hello = new Object();
    Object world = new Object();

    public static void main(String[] args) throws InterruptedException {
        for(int i=0; i<6;i++){
            Runnable helloTask = new Runnable(){
                @Override
                public void run(){
                    new ThreadSeq().printHello();
                }
            };

            Runnable worldTask = new Runnable(){
                @Override
                public void run(){
                    new ThreadSeq().printWorld();
                }
            };

            Thread t1 = new Thread(helloTask);
            Thread t2 = new Thread(worldTask);
            t1.start();
            t1.join();
            t2.start();
            t2.join();
        }

    }

    public void printHello(){
        synchronized (hello) {
            System.out.println("Hello");
        }
    }

    public void printWorld(){
        synchronized (world) {
            System.out.println("World");
        }
    }
}
wko9yo5t

wko9yo5t7#

简单地说,我们可以使用 wait() 以及 notify() 不创建任何额外的对象。

public class MainHelloWorldThread {

    public static void main(String[] args) {

        HelloWorld helloWorld = new HelloWorld();

            Thread t1 = new Thread(() -> {
                try {
                    helloWorld.printHello();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            Thread t2 = new Thread(() -> {
                try {
                    helloWorld.printWorld();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

        // printHello() will be called first
        t1.setPriority(Thread.MAX_PRIORITY);

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

    }
}

class HelloWorld {

    public void printHello() throws InterruptedException {

        synchronized (this) {
            // Infinite loop
            while (true) {
                // Sleep for 500ms
                Thread.sleep(500);
                System.out.print("Hello ");

                wait();
                // This thread will wait to call notify() from printWorld()

                notify();
                // This notify() will release lock on printWorld() thread
            }
        }
    }   

    public void printWorld() throws InterruptedException {

        synchronized (this) {
            // Infinite loop
            while (true) {
                // Sleep for 100ms
                Thread.sleep(100); 
                System.out.println("World");

                notify();
                // This notify() will release lock on printHello() thread

                wait();
                // This thread will wait to call notify() from printHello()
            }
        }
    }
}

相关问题