Montag, Januar 27, 2020

Drucken „Hallo“ und „Welt“ mehrere Male unter Verwendung von zwei threads in java

Davon ausgehen, dass ein thread „Hello“ und anderen Drucke der „Welt“. Ich habe es erfolgreich für eine Zeit, wie folgt:
Paket threading;

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

Wie mache ich es für mehrere Zeit-Druck, sagen wir für 5 mal? Ich versucht, indem Sie für die Schleife um den synchronisierten block, aber keinen nutzen.

  • Vielleicht sollten Sie sich Gedanken über zwei Schleifen.
  • Vielleicht sollten Sie darüber nachdenken, mit CyclicBarrier.
  • Dies ist nicht gewährleistet, dass Sie immer print Hallo Welt! – der Haupt-thread unterbrochen werden könnte zwischen mt.start(); und synchronisiert(mt)

7 Kommentare

  1. 2
    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");
            }
        }
    }
  2. 7

    Hier zwei voneinander abhängige threads, wir brauchen zwei Objekte synchronisieren. Sie könnte eines von vielen Dingen. eine ganze Zahl, ein weiteres Objekt; ein boolescher Wert ein anderes Objekt; beide Objekt; beide Semaphore und so weiter. die Synchronisierung Technik könnte entweder Monitor oder Semaphore, wie Sie möchten, aber Sie müssen zwei sein.

    Habe ich modifiziert Ihren code zu verwenden semaphore statt Monitor. Die Semaphore funktioniert mehr transparent. Sehen Sie die acquire-und release passiert. Monitore sind auch höhere Konstrukte. Daher Synchronisiert, arbeitet unter der Haube.

    Wenn Sie bequem mit dem folgenden code, dann können Sie wandeln es um Monitore statt.

        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();
                }
            }
        }
    • +1 für die Verwendung von Semaphoren – eine Verbesserung der AtomicBoolean Ansatz als zu erwerben ist, zu blockieren.
    • Können Sie schlagen alle nettes tutorial online für concurrent-Paket?
    • sehen Sie, ich bin nicht ganz sicher, wie tutor ein java-Paket. das Thema Parallelität selbst ist Recht verworren und ich bin kein champ. die beste ich kann nur sagen diesen link. obwohl es ist mehr wie ein Kurs als ein tutorial. aber ich konnte nicht mit weniger zufrieden. also, auf zum fröhlichen jagen…
  3. 3

    Hier ist das Ziel zum synchronisieren von threads so, dass wenn man es geschafft hat den anderen. Wenn ich es, es wären 2 threads den gleichen code mit unterschiedlichen Daten. Jeder thread hat seine eigenen Daten ("Hello" und true T1, "World" und false zu t2), und teilen sich eine variable turn sowie ein separates Sperrobjekt.

    while(/* I need to play*/){
      synchronized(lock){
        if(turn == myturn){
          System.out.println(mymessage);
          turn = !turn; //switch turns
          lock.signal();
         }
         else{
           lock.wait();
         }
      }
    }
    • Können Sie schlagen alle nettes tutorial online für concurrent-Paket?
  4. 3

    Bevor Sie beginnen zu versuchen, um es zu fünf Zeiten, die Sie benötigen, um sicherzustellen, dass es mal funktioniert!

    Dein code ist nicht gewährleistet, dass Sie immer print Hallo Welt! – der Haupt-thread unterbrochen werden könnte, bevor die Sperre von mt (beachten Sie, dass sperren auf thread-Objekten ist generell keine gute Idee).

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

    Einem Ansatz wird das verallgemeinern zu tun, das viele Male, ist die Verwendung einer atomaren booleschen

    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);
            }
        }
    }
    • Sie sicher, dass das funktioniert…?? Ich habe versucht, und es gedruckt Hallo fünf mal, aber keine Welt. 🙁
    • Es funktioniert hier, obwohl ich bearbeitet habe, ein paar Momente nach der Veröffentlichung zu beheben einen kleinen Fehler – saidHello.set(false) nach dem System.aus.println(„Hallo“) wurde korrigiert, um saidHello.set(true)
    • saidHello ist nicht definiert in MyThread. machen es Arbeit, die ich zu bestehen hatte es von Inter-Thread zu MyThread. Dann funktionierte es wie ein Charme. gute Arbeit.
    • Ich werde Bearbeiten Sie Sie entsprechend.
    • Danke @selig für deine Zeit und postest die Lösung. Ja, AtomicBoolean ist ein Weg, ich habe versucht mit dem traditionellen Ansatz. Dank sehr viel!!
    • Können Sie schlagen alle nettes tutorial online für concurrent-Paket?
    • In der Regel verwende ich die offizielle tutorials und finden Sie hilfreich, andere haben vielleicht alternative Vorschläge.

  5. 1

    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;
    }
  6. 0

    Gibt es zwei Threads, und beide hat seine eigenen Daten („Hallo“ und wahr zu ht, „Welt“ und false wt), und teilen sich eine variable 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();               
        }
    }
  7. 0

    In einfacher Weise kann dies mithilfe wait() und notify() ohne ein extra Objekt.

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

Kostenlose Online-Tests