如何在java中同时运行两个线程

如何在java中同时运行两个线程,java,multithreading,Java,Multithreading,我是java新手,我正在努力学习线程 我希望有一个alternatehello这是线程1和hello这是线程2的输出。但我得到的结果如下: hello this is thread one hello this is thread one hello this is thread one hello this is thread one hello this is thread one hello this is thread two hello this is thread two hello

我是java新手,我正在努力学习线程

我希望有一个alternate
hello这是线程1
hello这是线程2
的输出。但我得到的结果如下:

hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two
下面是我的代码。有谁能帮我解释一下为什么我得到的结果与预期相反。我能做什么来并行运行这两个线程呢

public class ThreadDemo {
    public static void main(String args[]) {

        // This is the first block of code
        Thread thread = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread one");
                }
            }
        };

        // This is the second block of code
        Thread threadTwo = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread two");
                }
            }
        };

        // These two statements are in the main method and begin the two
        // threads.
        // This is the third block of code
        thread.start();

        // This is the fourth block of code
        threadTwo.start();
    }
}
公共类ThreadDemo{
公共静态void main(字符串参数[]){
//这是第一段代码
线程线程=新线程(){
公开募捐{
对于(int i=0;i<10;i+=2){
System.out.println(“你好,这是线程一”);
}
}
};
//这是第二段代码
线程threadTwo=新线程(){
公开募捐{
对于(int i=0;i<10;i+=2){
System.out.println(“您好,这里是线程二”);
}
}
};
//这两条语句位于main方法中,并从这两条语句开始
//线程。
//这是第三段代码
thread.start();
//这是第四段代码
threadTwo.start();
}
}

您的代码也可以工作..在第一个对象中添加睡眠

   // This is the first block of code
        Thread thread = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread one");
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        };
//这是第一段代码
线程线程=新线程(){
公开募捐{
对于(int i=0;i<10;i+=2){
System.out.println(“你好,这是线程一”);
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
};

根据CPU和/或CPU内核的数量,多线程只能由您的CPU通过在调度另一个线程之前给每个线程一定的时间来模拟。另见

此外,考虑到当今的CPU和许多内核及其速度,也可能是第一个线程的执行在第二个线程开始之前就已经完成了

另外,两个线程都在为锁定
系统.out
而斗争,因此它们将彼此锁定


让线程运行更长的时间(更高的迭代次数),您将看到预期的交错。

仅仅因为线程可能交错并不意味着它们会交错。你的线程运行得太快了。尝试添加
Thread.sleep()
,使它们运行更长时间。

这里的问题是PrintStream是
同步的
,这是不公平的

    final Lock lock = new ReentrantLock(true); //create fair lock
                        //after running this code change it to
                        //ReentrantLock(false); to see what happens

    // This is the first block of code
    Thread thread = new Thread() {
        public void run() {
            for (int i = 0; i < 10; i += 2) {
                lock.lock();
                System.out.println("hello this is thread one");
                lock.unlock();
            }
        }

    };

    // This is the second block of code
    Thread threadTwo = new Thread() {
        public void run() {
            for (int i = 0; i < 10; i += 2) {
                lock.lock();
                System.out.println("hello this is thread two");
                lock.unlock();
            }
        }

    };

    // These two statements are in the main method and begin the two
    // threads.
    // This is the third block of code
    thread.start();

    // This is the fourth block of code
    threadTwo.start();
final Lock=new ReentrantLock(真)//创建公平锁
//运行此代码后,将其更改为
//可重入锁定(假);看看会发生什么
//这是第一段代码
线程线程=新线程(){
公开募捐{
对于(int i=0;i<10;i+=2){
lock.lock();
System.out.println(“你好,这是线程一”);
lock.unlock();
}
}
};
//这是第二段代码
线程threadTwo=新线程(){
公开募捐{
对于(int i=0;i<10;i+=2){
lock.lock();
System.out.println(“您好,这里是线程二”);
lock.unlock();
}
}
};
//这两条语句位于main方法中,并从这两条语句开始
//线程。
//这是第三段代码
thread.start();
//这是第四段代码
threadTwo.start();

当一个锁是公平的时,它会慢很多,但当它不像第一个锁那样公平时,它会在另一个线程有机会获得锁之前一遍又一遍地抓住它。公平的锁就像队列。无论是谁排队下一个获得它。

您的代码按预期工作,绝对不能保证您的实现将以您预期的预定义方式执行


我建议您研究实现多线程代码的其他方法,例如join()、sleep(),并找到一种更适合您的需要的方法。

如果您希望让线程的主体等待两个线程都运行,您可以使用类似于
CountDownLatch的方法,它可以阻塞,直到其内部计数器计数为零:

final CountDownLatch latch = new CountDownLatch(2);
Thread thread = new Thread() {
  @Override public void run() {
    latch.countDown();
    latch.await();  // Execution waits here until latch reaches zero.

    // Rest of the method.
  }
}
Thread threadTwo = new Thread() {
  @Override public void run() {
    latch.countDown();
    latch.await();  // Execution waits here until latch reaches zero.

    // Rest of the method.
  }
}

thread.start();
threadTwo.start();
(为了清楚起见,省略了异常处理)

这将保证两个线程的运行方法的“有趣的部分”将同时执行。但是,由于正在调用的
println()
方法的同步不公平,因此无法保证两个线程打印的消息将如何交错:

  • 有时它们可能“完美地”交错(1,2,1,2,…)
  • 有时,其中一些可能在打印时没有其他内容(1,1,2,1,2,2,…)
  • 有时,一个可能会在另一个之前打印所有消息(1,1,1,1,2,2,2)

    • 下面的代码正在运行

      public class ThreadDemo {
      
          public static void main(String args[]) throws InterruptedException {
      
              // This is the first block of code
              Thread thread = new Thread() {
                  public void run() {
                      for (int i = 0; i < 10; i += 2) {
                          System.out.println("hello this is thread one");
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException ex) {
                              Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
                          }
                      }
                  }
              };
      
              // This is the second block of code
              Thread threadTwo = new Thread() {
                  public void run() {
                      for (int i = 0; i < 10; i += 2) {
                          System.out.println("hello this is thread two");
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException ex) {
                              Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
                          }
                      }
                  }
              };
      
              // These two statements are in the main method and begin the two
              // threads.
              // This is the third block of code
              thread.start();
      
              // This is the fourth block of code
              threadTwo.start();
      
          }
      }
      
      公共类ThreadDemo{
      公共静态void main(字符串args[])引发InterruptedException{
      //这是第一段代码
      线程线程=新线程(){
      公开募捐{
      对于(int i=0;i<10;i+=2){
      System.out.println(“你好,这是线程一”);
      试一试{
      睡眠(100);
      }捕获(中断异常例外){
      Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE,null,ex);
      }
      }
      }
      };
      //这是第二段代码
      线程threadTwo=新线程(){
      公开募捐{
      对于(int i=0;i<10;i