Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用2个线程打印偶数和奇数_Java_Multithreading - Fatal编程技术网

Java 使用2个线程打印偶数和奇数

Java 使用2个线程打印偶数和奇数,java,multithreading,Java,Multithreading,您好,我正在尝试使用两个线程(名为EvenThread和OddThread)打印偶数和奇数,有时我得到了正确的结果,有时没有,请任何人帮助我 package com.java8; public class EvenOddExample { public static synchronized void print(int i,String name){ System.out.println(i+"--->"+name); } public

您好,我正在尝试使用两个线程(名为EvenThread和OddThread)打印偶数和奇数,有时我得到了正确的结果,有时没有,请任何人帮助我

package com.java8;

public class EvenOddExample {

    public static synchronized void print(int i,String name){
            System.out.println(i+"--->"+name);
    }
    public static void main(String[] args) throws InterruptedException {
        EvenThread e=   new EvenThread();
        e.start();
        OddThread o=new OddThread();
        o.start();

    }
    public static class EvenThread extends Thread{

        public void run() {
            for(int i=0;i<10;i++){
                if(i%2==0){
                    print(i,"Even");
                }else{
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

        }

    }

    public static class OddThread extends Thread{

        @Override
        public void run() {
            for(int i=1;i<10;i++){
                if(i%2!=0){
                    print(i,"Odd");
                }else{
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

        }

    }
}
package com.java8;
公共类的例子{
公共静态同步无效打印(int i,字符串名称){
System.out.println(i+“-->”+名称);
}
公共静态void main(字符串[]args)引发InterruptedException{
EvenThread e=新的EvenThread();
e、 start();
OddThread o=新的OddThread();
o、 start();
}
公共静态类EvenThread扩展线程{
公开募捐{

对于(int i=0;i您需要在两个线程之间发送一些信号。将
synchronized
放在
print
方法上可以简单地保证一次只能有一个线程进入该方法。要将线程按顺序放入
Object.wait()
Object.notify{All}()
方法,可以使用

实际上,这是某种发送方-接收方同步问题。根据所述问题的示例(请阅读本页以了解此同步的工作原理),我修改了您的代码。此外,我使用了
ExecutorService
Callable
,而不是扩展
线程
,:

import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类的例子{
私有静态布尔值evensTurn=true;
私有静态对象监视器=新对象();
公共静态无效打印(int i,字符串名称){
System.out.println(i+“-->”+名称);
}
公共静态void main(字符串[]args)引发InterruptedException{
final ExecutorService ExecutorService=Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(新的OddCallable());
executorService.shutdown();
}
公共静态类EvenCallable实现了Callable{
@凌驾
public Void call()引发InterruptedException{
对于(int i=0;i<10;i++){
如果(i%2==0){
同步(监视器){
而(!evensTurn){//不轮到你了?
monitor.wait();//在循环中等待monitor处理虚假唤醒
}
打印(i,“偶数”);
evensTurn=false;//需要运行下一个奇数
monitor.notifyAll();//唤醒奇数线程
}
}否则{
睡眠(1000);
}
}
返回null;
}
}
公共静态类OddCallable实现了Callable{
@凌驾
public Void call()引发InterruptedException{
对于(int i=1;i<10;i++){
如果(i%2!=0){
同步(监视器){
while(evensTurn){
monitor.wait();
}
印刷品(i,“奇数”);
evensTurn=true;
monitor.notifyAll();
}
}否则{
睡眠(1000);
}
}
返回null;
}
}
}

synchronized用于锁定另一个线程的访问,当锁定的对象空闲时,它不保证下一个被称为线程。您可以使用信号量进行线程间通信:

  private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};

  static void print(int i, String name) {
    try {
      semaphores[(i + 1) % 2].acquire();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    System.out.println(i + "--->" + name);
    semaphores[i % 2].release();
  }
公共类打印机{
静态布尔标志=true;
公共静态void main(字符串[]args){
类奇数实现可运行{
@凌驾
公开募捐{

对于(int i=1;i“correct result”是什么意思?让eventhread从2开始,oddThread从1开始,循环(打印->将2添加到值)更改但同样发生1->奇数2->偶数3->奇数4->偶数6->偶数5->奇数8->偶数7->奇数9->奇数你的意思是有时
print
在一行中打印几个奇数,例如?因为你将
synchronized
放在静态方法上,所以当调用
print
。这并不意味着一个线程不能连续多次调用
print
。是的@michalk确切地说,问题是是是的,这样做可能会跳过一半的数字这绝对是错误的!!!你的睡眠在哪里()?你可以尝试添加睡眠()在不同的延迟情况下,您会看到它有时会卡住,无法打印到10
  private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};

  static void print(int i, String name) {
    try {
      semaphores[(i + 1) % 2].acquire();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    System.out.println(i + "--->" + name);
    semaphores[i % 2].release();
  }
public class EvenOddPrinter {
    static boolean flag = true;

    public static void main(String[] args) {
        class Odd implements Runnable {

            @Override
            public void run() {
                for (int i = 1; i <= 10;) {
                    if (EvenOddPrinter.flag) {
                        System.out.println(i + "--->odd");
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }
                }
            }

        }

        class Even implements Runnable {

            @Override
            public void run() {
                for (int i = 2; i <= 10;) {
                    if (!EvenOddPrinter.flag) {
                        System.out.println(i + "---->even");
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }
                }

            }

        }
        Runnable odd = new Even();
        Runnable even = new Odd();
        Thread t1 = new Thread(odd, "Odd");
        Thread t2 = new Thread(even, "Even");
        t1.start();
        t2.start();
    }
}