设置线程Java的优先级

时间:2013-11-23 08:40:37

标签: java multithreading

这可能是一个非常愚蠢的问题,但我尝试在java程序中为几个线程设置优先级,但似乎我开始每个线程的顺序只决定哪一个更受青睐。

我正在尝试运行4个任务并为每个任务增加4个单独的计数器。然后我将主线程休眠10秒,同时4个线程运行并递增它们的计数器。一旦主线程恢复,程序在打印最终计数值后终止。

我得到的输出是这样的:

工作1: 5876

工作2: 6546

工作3: 6020

工作4: 0

即使运行作业4的线程具有最高优先级。

我认为我在这里有一些严重的概念问题......也许我想要做的不是我在节目中做的事情。请帮我。先谢谢你。

class Task1 implements Runnable
{
    public int count=0; 
    public void run()
    {
        while(true)         
        count++;

    }
}

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

        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        Task1 job1=new Task1();
        Task1 job2=new Task1();
        Task1 job3=new Task1();
        Task1 job4=new Task1();
        Thread t1=new Thread(job1);
        Thread t2=new Thread(job2);
        Thread t3=new Thread(job3);
        Thread t4=new Thread(job4);

        t1.setPriority(1);
        t2.setPriority(3);
        t3.setPriority(5);  
        t4.setPriority(7);  

        try
        {   
            Thread.sleep(10000);
        }
        catch(Exception e)
        {
        }

        t1.start();
        t2.start();
        t3.start();
        t4.start();



        System.out.println("Job 1:  "+job1.count);
        System.out.println("Job 2:  "+job2.count);
        System.out.println("Job 3:  "+job3.count);
        System.out.println("Job 4:  "+job4.count);
        System.exit(1);

    }

}

4 个答案:

答案 0 :(得分:2)

您的基准测试有几个大问题。

  1. 线程不会同时开始运行。启动一个线程是一项代价高昂的操作,当你开始第四个线程时,第一个线程已经有时间计算了。您应该使用CountDownLatch来确保所有线程同时开始计数(大约)。
  2. 您正在访问主线程中每个线程写入的变量,而不进行任何同步。因此主线程可以看到一个不是计数器实际值的值。您需要将count变量设置为volatile,或者使用AtomicInteger。
  3. 你没有给线程留足够的时间。例如,您的主线程在它甚至有机会开始执行之前打印最后启动的线程的值。您需要给调度程序一些时间来安排每个线程并应用优先级。
  4. 我不知道你有多少核心。但是如果你有4个,那么每个线程都可能在自己的核心上运行,并且根本不会使用优先级,因为它们不会相互争斗以获得一些CPU时间。使用更多线程,以便实际上有一些争用。

答案 1 :(得分:1)

最好在任务中使用锁定所有线程必须等待启动信号。否则你不能确保他们开始并行。 这是一个简单的使用CountDownLatch的解决方案,确保所有的tas同时开始。

public class Threadcount {

    static CountDownLatch s = new CountDownLatch(4);
    static volatile boolean run=true;

    static class Task1 implements Runnable {
        public long count = 0;

        public void run() {
            s.countDown();
            try {
                s.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (run)
                count++;

        }
    }

    public static void main(String[] args) {

        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        Task1 job1 = new Task1();
        Task1 job2 = new Task1();
        Task1 job3 = new Task1();
        Task1 job4 = new Task1();
        Thread t1 = new Thread(job1);
        Thread t2 = new Thread(job2);
        Thread t3 = new Thread(job3);
        Thread t4 = new Thread(job4);

        t1.setPriority(1);
        t2.setPriority(3);
        t3.setPriority(5);
        t4.setPriority(7);

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }
        run = false;

        System.out.println("Job 1:  " + job1.count);
        System.out.println("Job 2:  " + job2.count);
        System.out.println("Job 3:  " + job3.count);
        System.out.println("Job 4:  " + job4.count);

    }

答案 2 :(得分:0)

您的线程执行的时间非常短。如果您执行的时间更长,则可能会在更高优先级的线程中看到更多计数。即便如此,主要的是JVM无法保证在程序运行时可以看到这种计数差异。 如果您的功能依赖于一个线程在其他线程之前完成,请浏览Thread join。但是,在您的特定情况下,连接将不起作用,因为线程在无限循环中运行

答案 3 :(得分:0)

Java API声明:

  

每个帖子都有优先权。执行具有更高优先级的线程   优先于优先级较低的线程。

但是,如果将考虑线程优先级,则取决于操作系统,同一操作系统的版本或不同JVM之间可能不同的调度算法。因此,依赖线程优先级来实现java程序的正确性被认为是一种不好的做法,因为如果在不同的操作系统或不同的JVM上运行,这可能会导致意外行为。