Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 当一个线程到达其目标时,其他线程停止_Java_Multithreading_Netbeans - Fatal编程技术网

Java 当一个线程到达其目标时,其他线程停止

Java 当一个线程到达其目标时,其他线程停止,java,multithreading,netbeans,Java,Multithreading,Netbeans,我目前正在努力理解多线程的Java概念。我阅读了一个教程,其中使用了龟兔示例来解释多线程的概念,并且在很大程度上我理解了视频教程的语法和逻辑。在视频教程的最后,Youtuber给出了一个任务,涉及将多线程应用于奥运会赛道 使用示例中的knowledege,我能够创建10个线程(代表运动员),它们在一个循环中运行,执行100次(代表100米) 我的挑战是,当线程调度程序使一名运动员比其他9名运动员先跑100米时,其余9条线程始终无法完成比赛。在标准赛道上通常不是这样。事实上,一个叫做Usain B

我目前正在努力理解多线程的Java概念。我阅读了一个教程,其中使用了龟兔示例来解释多线程的概念,并且在很大程度上我理解了视频教程的语法和逻辑。在视频教程的最后,Youtuber给出了一个任务,涉及将多线程应用于奥运会赛道

使用示例中的knowledege,我能够创建10个线程(代表运动员),它们在一个循环中运行,执行100次(代表100米)

我的挑战是,当线程调度程序使一名运动员比其他9名运动员先跑100米时,其余9条线程始终无法完成比赛。在标准赛道上通常不是这样。事实上,一个叫做Usain Bolts的螺纹先达到100,并不意味着Yohan Blake应该停止运行,如果他当时在90米

我还对获取每个线程的距离感兴趣(注意,它们都使用相同的变量),这样我就可以使用函数返回比赛结束时每个线程的位置

我所做的(不起作用): 1) 我尝试使用if-else构造(包含九个“else” 语句)将每个执行线程的距离分配给一个新的整数变量。(使用Thread.currentThread().getName()属性和每个线程的名称)但这对我来说不太合适。这是一次尝试,仅利用运动员的距离为他们提供位置,但对9名未完成比赛的运动员没有任何影响。
2) 我还尝试在运行时使用ArrayList填充距离,但由于一些奇怪的原因,每次它想要添加另一个距离时,这仍然会覆盖距离

以下是我的代码:

package olympics100meters;

import java.util.ArrayList;

public class HundredMetersTrackRules implements Runnable {
public static String winner;

public void race() {
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread    ().getName  ()+" is "+distance+" meters.");


boolean isRaceWon=this.isRaceWon(distance);
if (isRaceWon) {
ArrayList<Integer> numbers = new ArrayList();
numbers.add(distance);
System.out.println("testing..."+numbers);
break;
}

}
}


private boolean isRaceWon(int totalDistanceCovered) {
   boolean isRaceWon=false;
   if ((HundredMetersTrackRules.winner==null)&&    (totalDistanceCovered==50)) {
   String winnerName=Thread.currentThread().getName();
   HundredMetersTrackRules.winner=winnerName;
   System.out.println("The winner is "+HundredMetersTrackRules.winner);
   isRaceWon=true;
   }

   else if (HundredMetersTrackRules.winner==null) {
   isRaceWon=false;
   }

   else if (HundredMetersTrackRules.winner!=null) {
   isRaceWon=true;
   }
   return isRaceWon;
}

public void run() {
this.race();
}     
}
  • 我的挑战是。。。剩余的9个线程始终无法完成其比赛

  • 这是由
    isRaceWon()方法实现引起的。你在每一个跑步者的每一米处检查它。当第一名运动员达到100米时,在每个跑步者环路的下一个步骤中调用
    中断
    (每个环路都赢得比赛)

    顺便说一句,使用
    volatile statuc String
    作为获胜者的名字是有意义的,以避免java内存模型的歧义

  • 我还对获取每条线的距离感兴趣,这样我就可以在比赛结束时使用函数返回每条线的位置

  • 如果最终目标是获得该职位,请创建一个类字段
    public List finishingOrder=new ArrayList
    和一个方法
    finish

    private synchronized finish() {
       finishingOrder.add(Thread.currentThread().getName())
    }
    
    并在“运行”循环后调用它


    不要忘记调用
    join()
    对于主
    中的所有运行线程
    。之后,
    finishingOrder
    将按完成顺序包含名称。

    下面的代码片段将导致
    isRaceWon
    在共享
    winner
    字段设置为非空时,对
    百米规则
    的每个实例返回true(即某人获胜):

    这反过来会导致
    race()
    中的循环对于
    Runnable
    的每个实例都中断。
    run()
    方法退出,终止线程


    这个问题只是一个逻辑错误,并不是真正特定于线程。但是,正如其他海报所提到的,您也可以在这段代码中采用一些线程最佳实践,例如对线程共享的字段使用
    volatile

    实际上,对于争用,您需要一次启动所有线程,然后只启动它的争用。
    CountDownLatch
    是实现或编写竞赛程序的更好方法

    我们还可以通过许多其他方式编写Race程序,而无需使用
    CountDownLatch
    。 如果我们需要使用基本/低级实现,那么我们可以在同步块中使用
    volatile
    布尔标志和计数器变量,或者使用
    wait()
    notifyAll()
    逻辑等

    在for循环中引入了一些时间延迟。然后只有你才能感受到这种体验。为什么呢?因为你没有一次启动所有线程

    希望您正在练习初始/基本级别,因此我只做了一些更改,以便更好地理解并解决您的所有问题

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    class HundredMetersTrackRules implements Runnable {
        public static Main main;
        
        HundredMetersTrackRules(Main main){
            this.main=main;
        }
        
        public static String winner;
        public void race() {
            try{
                   System.out.println(Thread.currentThread().getName()+" Waiting for others...");
                   while(!Main.start){
                        Thread.sleep(3);
                   }
                for (int distance=1;distance<=50;distance++) {
                    System.out.println("Distance covered by "+Thread.currentThread().getName()+" is "+distance+" meters.");
                    Thread.sleep(1000);
                }
                synchronized(main){
                    Main.finish--;
                }
                Main.places.add(Thread.currentThread().getName());
             }catch(InterruptedException ie){
                ie.printStackTrace();  
             }
        }
        
        public void run() {
        this.race();
        }     
    }
    public class Main
    {
       public static volatile boolean start = false;
       public static int finish = 5;
       final  static List<String> places = 
                Collections.synchronizedList(new ArrayList<String>());
       public static void main(String[] args) {
             
       HundredMetersTrackRules racer=new HundredMetersTrackRules(new Main());
       Thread UsainBoltThread=new Thread(racer,"UsainBolt");
       Thread TysonGayThread=new Thread (racer,"TysonGay");
       Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
       Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
       Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
    
       UsainBoltThread.start();
       TysonGayThread.start();
       AsafaPowellThread.start();
       YohanBlakeThread.start();
       JustinGatlinThread.start();
       
       Main.start=true;
       
       while(Main.finish!=0){
            try{
                Thread.sleep(100);
            }catch(InterruptedException ie){
                ie.printStackTrace();  
            }
        }
        
        System.out.println("The winner is "+places.get(0));
        System.out.println("All Places :"+places);
      }
    }
    
    import java.util.ArrayList;
    导入java.util.List;
    导入java.util.Collections;
    类HundredMetersTrackRules实现可运行{
    公共静态主体;
    百米规则(主){
    this.main=main;
    }
    公共静态字符串赢家;
    公开竞逐(){
    试一试{
    System.out.println(Thread.currentThread().getName()+“等待他人…”);
    而(!Main.start){
    睡眠(3);
    }
    
    对于(int distance=1;distanceArray list不是线程安全的。我看不到通常用于并发的同步关键字…除了arraylist之外,我没有展示您如何处理竞争,可能使用blockingqueue或其他安全的东西,或者使用密钥工作同步。如果您想编写灵活而健壮的多线程代码,您应该定义I尽量避免直接寻址Thread类。使用Runnable定义任务,并通过ExecutorService执行任务。这样,您就可以控制执行流和停止条件。网络上有许多ExecutorService用法的示例。谢谢。但是有什么方法可以让这个程序按我的要求执行吗直接使用Thread类可以吗?我想确定多线程的基本概念。恐怕您需要发布更多的代码以便我们找到问题。是的,直接使用
    Thread
    类可以做到这一点,但首先请注意
    ArrayList
    不是线程安全的警告,并将其包装线内-
    else if (HundredMetersTrackRules.winner!=null) {
       isRaceWon=true;
    }
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    class HundredMetersTrackRules implements Runnable {
        public static Main main;
        
        HundredMetersTrackRules(Main main){
            this.main=main;
        }
        
        public static String winner;
        public void race() {
            try{
                   System.out.println(Thread.currentThread().getName()+" Waiting for others...");
                   while(!Main.start){
                        Thread.sleep(3);
                   }
                for (int distance=1;distance<=50;distance++) {
                    System.out.println("Distance covered by "+Thread.currentThread().getName()+" is "+distance+" meters.");
                    Thread.sleep(1000);
                }
                synchronized(main){
                    Main.finish--;
                }
                Main.places.add(Thread.currentThread().getName());
             }catch(InterruptedException ie){
                ie.printStackTrace();  
             }
        }
        
        public void run() {
        this.race();
        }     
    }
    public class Main
    {
       public static volatile boolean start = false;
       public static int finish = 5;
       final  static List<String> places = 
                Collections.synchronizedList(new ArrayList<String>());
       public static void main(String[] args) {
             
       HundredMetersTrackRules racer=new HundredMetersTrackRules(new Main());
       Thread UsainBoltThread=new Thread(racer,"UsainBolt");
       Thread TysonGayThread=new Thread (racer,"TysonGay");
       Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
       Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
       Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
    
       UsainBoltThread.start();
       TysonGayThread.start();
       AsafaPowellThread.start();
       YohanBlakeThread.start();
       JustinGatlinThread.start();
       
       Main.start=true;
       
       while(Main.finish!=0){
            try{
                Thread.sleep(100);
            }catch(InterruptedException ie){
                ie.printStackTrace();  
            }
        }
        
        System.out.println("The winner is "+places.get(0));
        System.out.println("All Places :"+places);
      }
    }