【问题标题】:How to make Java threads to get fair amount of CPU time如何使 Java 线程获得相当多的 CPU 时间
【发布时间】:2014-01-20 19:38:42
【问题描述】:

我是 Java 新手。在发布这个问题之前,我已经搜索了这个网站。如果我的问题看起来很愚蠢,请原谅我。

下面给出了我正在寻找答案的代码。

我的目的是让 4 名选手参加 100 米跑比赛。 Main 线程以最高优先级运行,因此它可以检查每个玩家的进度。我在主线程和子线程中都编写了 Yield 方法,认为主线程和子线程都会获得相当多的 CPU 时间。

该程序每次运行都会产生以下三种不同的输出。

  1. 它会产生““Gun is Fired”消息,然后控制台中不会显示任何消息。在这种情况下,看起来主线程正在独占 CPU。

  2. 某个时候,一个“玩家”对象获得所有 CPU 时间并赢得比赛,而其他玩家对象都没有获得 CPU 时间。

  3. 很少有所有播放器实例都获得相当多的 CPU 时间,我可以看到每个播放器实例都在控制台中生成消息。

我系统中的处理器是 core 2 duo。

是否可以一直实现上述“第三输出”?

class Player implements Runnable{

    int noOfMetersCrossed = 0;
    Gun gun;
    String name;

    Player(Gun gun,String name) {
        this.gun = gun;
        this.name = name;
        new Thread(this,name).start();
    }

    public void run() {
        try{
            synchronized(gun){
                gun.wait();         
            }
        } catch(InterruptedException e){

        }
        System.out.println(name+" started running");
        while(noOfMetersCrossed < 100){
            noOfMetersCrossed++;                
            System.out.println(name + " crossed " + noOfMetersCrossed + " meters");
            Thread.yield();
        }
    }

}

class Gun {
    void fire(){
        synchronized(this){
            System.out.println("Gun is Fired");
            notifyAll();
        }
    }
}


public class Refree {
    public static void main(String arg[]){
        Gun gun = new Gun();
        Player participants[] = new Player[4];

        for(int i=0;i < 4;i++) {
            participants[i] = new Player(gun, "Player "+i);
        }
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

        gun.fire();
        findWinner(participants);
    }   

    static void findWinner(Player participants[]){      
        outer: while(true){

            Thread.yield();
            for(int i=0;i <4;i++) {
                if (participants[i].noOfMetersCrossed == 100){
                    System.out.println("The winner is " + participants[i].name);
                    break outer;                    
                } 
            }
        }

    }
}

【问题讨论】:

  • 我原谅你亲爱的用户
  • 请注意,根据处理器/操作系统,您设置的优先级可能会被完全忽略。
  • 在这么小的时间尺度上,我不确定是否有可能,如果不使用同步原语,以便线程在领先时等待其他线程。我怀疑如果你让“竞赛”持续更长时间,你会看到线程之间的时间分配更均匀。
  • 尝试使noOfMetersCrossed volatile,因为这里也存在可见性问题。如果没有围绕变量进行任何同步,裁判线程有权始终看到 0。
  • 时间片太长 :) 1. notyfyAll 是顺序的而不是并行的,所以一个线程启动并且在一个时间片达到 100m,在另一个片中主线程检测到它并停止 JVM,所以其他线程没有机会使一些cpu使用。尝试制作比 i++ 更复杂的东西。顺便说一句:最好让 noOfMetersCrossed 变为 volatile 以确保其他线程的正确可见性。

标签: java multithreading


【解决方案1】:

操作系统尝试在线程之间平均分配 CPU。 我不会使用循环等待获胜者,而是使用 CountDownLatch 或类似的东西,因为您的 findWinner 与跑步者一起竞争 CPU。

【讨论】:

    【解决方案2】:

    任何人在 7 年后看到这个,在繁忙循环中的任何地方使用 System.{out|err}.println() 对于这种“测量”来说都是一个坏主意,因为控制台输出在相应的控制台流。如果没有,您会从多个线程输出部分和混乱的行。

    因此,该循环中的控制台输出具有副作用,使这 4 个线程相互等待以在控制台上输出消息。更糟糕的是:监视器锁是不公平的。

    【讨论】:

      猜你喜欢
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多