当前位置: 动力学知识库 > 问答 > 编程问答 >

multithreading - Understanding "priority" in java threads

问题描述:

I am new to the world of java and threads..I was just going through an example code as below:-

package com.alice.learnthread;

class NewThread implements Runnable{

Thread t;

long clicker=0;

private volatile boolean running=true;

NewThread(int p){

t=new Thread(this);

t.setPriority(p);

}

public void run(){

while(running){

clicker++;

}

}

public void stop(){

running=false;

}

public void start(){

t.start();

}

}

 public class TestThread {

public static void main(String[] args){

Thread r=Thread.currentThread();

r.setPriority(Thread.MAX_PRIORITY);

NewThread hi=new NewThread(Thread.NORM_PRIORITY+2);

NewThread lo=new NewThread(Thread.NORM_PRIORITY-2);

hi.start();

lo.start();

try{

r.sleep(5000);

}catch(InterruptedException e){

System.out.println("caught");

}

hi.stop();

lo.stop();

try{

hi.t.join();

lo.t.join();

}catch(InterruptedException e){

System.out.println("cau1");

}

System.out.println("hi = "+hi.clicker+" lo="+lo.clicker);

}

}

However according to the output in the book the thread with high priority should have higher value for the variable clicker. But in my case the values for the variable clicker is much higher for the lower priority thread than for the higher priority one.The output is like below for me:-

hi = 2198713135 lo=2484053552

Does this not mean that lower priority thread got more CPU time than the higher priority one...Am i missing something..The results are the same(higher clicker value for the lower priority thread) on both ubuntu and win7...

网友答案:

As sul said, priority is more a hint than a contract to the JVM. In your case, your result can be explained by several theories:

  • The second thread runs faster because it takes the benefits of the compilation of the first one and is stopped after the first one.
  • The facts that the while loop check the value of a volatile variable force the jvm to actualize the value and during this time could give the other thread the CPU.
  • The stop methods takes lot of time to stop the thread.

That is just some facts to say that how thread act is unpredictable. For example try to start the low priority thread first and I am sure you will have a different result.

Also, try this :

public class TestThread
{
    public static void main(String[] args){
        Thread r=Thread.currentThread();
        r.setPriority(Thread.MAX_PRIORITY);
        NewThread hi=new NewThread(Thread.MAX_PRIORITY);
        NewThread lo=new NewThread(Thread.MIN_PRIORITY);
        hi.start();
        lo.start();
        try{
            r.sleep(5000);
        }catch(InterruptedException e){
            System.out.println("caught");
        }
        hi.interrupt();
        lo.interrupt();

        System.out.println("hi="+hi.clicker);
        System.out.println("lo="+lo.clicker);
    }
}
class NewThread extends Thread{
    long clicker=0;

    NewThread(int p){
        setPriority(p);
    }
    public void run(){
        while(true){
            clicker++;
        }
    }
}

I am sure that removing the volatile variable and changing how the thread is stopped will give you an other result.

网友答案:

Thread priority in Java does not guarantee the intended behavior. It is just like a hint to the JVM. The actual behavior depends on the underlying OS.

Also, read this nice little para about Cooperative vs. Preemptive Threading: http://www.cafeaulait.org/course/week11/32.html

网友答案:

Threads are unpredictable in nature. The low priority thread run when high priority threads are not able to run due to some reasons, and moreover Thread priority isn't very meaningful when all threads are competing for CPU.

But yet when i executed the program above, i got the desired result as mention in your book.

hi = 1707497920 lo=1699648942

hi = 1702682202 lo=1685457297
网友答案:

I am finding on Windows 7 that if I increase the number of threads to the point where there is an actual fight over system resources, and increase the running time, the higher priority threads do an order of magnitude more clicks. Would be curious if this is not the case. I think your test case is too small both in number of threads to use up enough resources that they have to contend, and also in running time for JVM to bind to native threads.

   public static void main(String[] args) {
        Thread r = Thread.currentThread();
        r.setPriority(Thread.MAX_PRIORITY);
        List<NewThread> hiThreads = new LinkedList<NewThread>();
        List<NewThread> lowThreads = new LinkedList<NewThread>();
        for (int i = 0; i < 10; i++) {
            NewThread hi = new NewThread(Thread.NORM_PRIORITY + 2);
            NewThread lo = new NewThread(Thread.NORM_PRIORITY - 2);
            hiThreads.add(hi);
            lowThreads.add(lo);
            hi.start();
            lo.start();
        }
        try {
            r.sleep(30000);
        } catch (InterruptedException e) {
            System.out.println("caught");
        }
        for (NewThread h : hiThreads) {
            h.stop();
        }
        for (NewThread l : lowThreads) {
            l.stop();
        }
        try {
            for (NewThread h : hiThreads) {
                h.t.join();
            }
            for (NewThread l : lowThreads) {
                l.t.join();
            }
        } catch (InterruptedException e) {
            System.out.println("cau1");
        }
        long hiClicker = 0l;
        for (NewThread h : hiThreads) {
            hiClicker += h.clicker;
        }
        long lowClicker = 0l;
        for (NewThread l : lowThreads) {
            lowClicker += l.clicker;
        }
        System.out.println("hi = " + hiClicker + " lo=" + lowClicker);
    }
网友答案:

I wrote a small application to see how Java threads work at:

https://github.com/vinhqdang/java-thread-example

网友答案:

Just for those who looking for bit more explaination ... Following is the excerpt from "The Complete Reference, Java, Herbert Shieldt"

As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run any faster than a lower-priority thread if it is the only thread running. Instead, a thread’s priority is used to decide when to switch from one running thread to the next. This is called a context switch. The rules that determine when a context switch takes place are simple:

  • A thread can voluntarily relinquish control. This is done by explicitly yielding, sleeping, or blocking on pending I/O. In this scenario, all other threads are examined, and the highest-priority thread that is ready to run is given the CPU.
  • A thread can be preempted by a higher-priority thread. In this case, a lower-priority thread that does not yield the processor is simply preempted —no matter what it is doing— by a higher-priority thread. Basically, as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking
分享给朋友:
您可能感兴趣的文章:
随机阅读: