有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java多线程Hello World

使用两个线程,您应该打印“helloworld helloworld helloworld helloworld helloworld”

在两个线程中,一个线程应该打印“Hello:和另一个线程“World”

我可以用不同的类来实现这一点,比如hello和world各一个类 我也可以用一个内部类来实现它

有没有这样一种方法:只有一个主类而没有内部类


共 (3) 个答案

  1. # 1 楼答案

    这看起来怎么样?没有线程对特定的单词有特定的责任,但是通过使用两个Atomic可以很容易地确保线程处于锁定状态

    这个算法并不依赖于只有两个线程——正如你所看到的,它仍然适用于任意数量的线程,在本例中是42个。只要2个,甚至1个,它仍然可以正常工作

    public class HelloWorld implements Runnable {
      // The words.
      private final String[] words;
      // Which word to print next.
      private final AtomicInteger whichWord;
      // Cycles remaining.
      private final AtomicInteger cycles;
    
      private HelloWorld(String[] words, AtomicInteger whichWord, AtomicInteger cycles) {
        // The words to print.
        this.words = words;
        // The Atomic holding the next word to print.
        this.whichWord = whichWord;
        // How many times around we've gone.
        this.cycles = cycles;
      }
    
      @Override
      public void run() {
        // Until cycles are complete.
        while ( cycles.get() > 0 ) {
          // Must transit from this word
          int thisWord = whichWord.get();
          // to the next word.
          int nextWord = thisWord + 1;
          // Are we cycling?
          boolean cycled = false;
          if ( nextWord >= words.length ) {
            // We cycled!
            cycled = true;
            // Back to zero.
            nextWord = 0;
          }
          // Grab hold of System.out to ensure no race there either.
          synchronized ( System.out ) {
            // Atomically step the word number - must still be at thisWord for the step calculations to still be correct.
            if ( whichWord.compareAndSet(thisWord, nextWord)) {
              // Success!! We are the priveliged one!
              System.out.print(words[thisWord]);
              // Count the cycles.
              if ( cycled ) {
                // Just step it down.
                cycles.decrementAndGet();
              }
            }
          }
        }
      }
    
      public static void test() throws InterruptedException {
        // The words to print.
        String [] words = {"Hello ", "world. "};
        // Which word to print next (start at 0 obviously).
        AtomicInteger whichWord = new AtomicInteger(0);
        // How many cycles to print - 6 as specified.
        AtomicInteger cycles = new AtomicInteger(6);
        // My threads - as many as I like.
        Thread [] threads = new Thread[/*2*/42];
        for ( int i = 0; i < threads.length; i++ ) {
          // Make each thread.
          threads[i] = new Thread(new HelloWorld(words, whichWord, cycles));
          // Start it.
          threads[i].start();
        }
        // Wait for them to finish.
        for ( int i = 0; i < threads.length; i++ ) {
          // Wait for completion.
          threads[i].join();
        }
      }
    
      public static void main(String args[]) throws InterruptedException {
        System.out.println("HelloWorld:Test");
        test();
      }
    
    }
    
  2. # 2 楼答案

    Is there a way such that there's only one main class and and no inner class?

    当然。你可以把字符串传给你的主类。当然,棘手的部分是协调线程,以便它们实际打印出"HelloWorld",而不是"WorldHello"或其他排列。线程将并行运行,不保证顺序。这就是线程程序异步运行的全部意义。试图强制输出特定单词会否定使用线程的目的

    <;咆哮>;对我来说,这有点像是一个设计拙劣的计算机科学作业。使用线程编写的全部意义在于,它们独立地并行运行。协调通常发生在每个线程从工作队列中提取结果,然后将结果放入结果队列或其他东西时。任何时候,当你有一个线程程序需要这么多的协调时,你都不应该使用线程</咆哮>

    但是,由于每个人都反对我之前的答案,可能是因为它不能完美地解决他们的家庭作业问题,我将添加一些逻辑来协调这两个线程,并说出“Hello World…”

    这两个线程需要能够锁定某些内容,相互发出信号,并知道何时应该等待或打印。因此,我将添加一个boolean printHello,并锁定传入的公共锁定对象:

    public class HelloWorld implements Runnable {
    
        private static boolean printHello = true;
    
        private final String toPrint;
        private final boolean iPrintHello;
        private final Object lock;
    
        public static void main(String[] args) {
            final Object lock = new Object();
            // first thread prints Hello
            new Thread(new HelloWorld("Hello ", true, lock)).start();
            // second one prints World
            new Thread(new HelloWorld("World ", false, lock)).start();
        }
    
        public HelloWorld(String toPrint, boolean iPrintHello, Object lock) {
            this.toPrint = toPrint;
            this.iPrintHello = iPrintHello;
            this.lock = lock;
        }
    
        @Override
        public void run() {
            // don't let it run forever
            for (int i = 0; i < 1000 && !Thread.currentThread().isInterrupted(); ) {
                // they need to synchronize on a common, constant object
                synchronized (lock) {
                    // am I printing or waiting?
                    if (printHello == iPrintHello) {
                        System.out.print(toPrint);
                        // switch the print-hello to the other value
                        printHello = !printHello;
                        // notify the other class that it can run now
                        lock.notify();
                        i++;
                    } else {
                        try {
                            // wait until we get notified that we can print
                            lock.wait();
                        } catch (InterruptedException e) {
                            // if thread is interrupted, _immediately_ re-interrupt it
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                }
            }
        }
    }
    
  3. # 3 楼答案

    1. 如果你想让T1打印“Hello”,T2打印“World”,你的预期结果是“Hello World Hello World Hello World Hello World Hello World”

      T1必须先启动,T2由T1调用,否则可以将“World Hello World”作为输出

      我建议定制读写器或生产者/消费者结构,使用notify()notifyAll()方法唤醒其他线程

    2. 如果您不关心输出的格式,请使用Runnable接口和首选实现