簡體   English   中英

使用java中的兩個線程多次打印“Hello”和“world”

[英]Printing “Hello” and “world” multiple times using two threads in java

假設一個線程打印“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次? 我嘗試在同步塊周圍進行循環,但沒有用。

這是兩個相互依賴的線程,我們需要兩個同步對象。 它們可能是眾多事物之一。 一個整數,另一個對象; 一個布爾另一個對象; 兩個對象; 兩個信號量等等。 同步技術可以是你喜歡的Monitor或Semaphore,但它們必須是兩個。

我已修改您的代碼以使用信號量而不是Monitor。 信號量工作更透明。 您可以看到獲取和發布的情況。 監視器甚至是更高的構造。 因此同步在引擎蓋下工作。

如果您對以下代碼感到滿意,則可以將其轉換為使用監視器。

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

這里的目標是同步線程,以便在完成一個線程時通知另一個線程。 如果我必須這樣做,它將是2個線程執行具有不同數據的相同代碼。 每個線程都有自己的數據( "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();
     }
  }
}

在你開始嘗試讓它工作五次之前,你需要確保它工作一次!

您的代碼不能保證始終打印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);
        }
    }
}
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");
        }
    }
}

這是在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;
}

有兩個線程,兩者都有自己的數據(“Hello”,對於ht,“World”和false為false),並共享一個變量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();               
    }
}

以簡單的方式,我們可以使用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()
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM