简体   繁体   中英

Setting Priority for Thread Java

this may be a very silly question but I tried setting priority for a few threads in a java program but it seems like the order in which I start each thread only determines which one is more favored.

I am trying to run 4 Tasks and increment 4 separate counters for each Task. Then I am putting the main thread to sleep for 10 sec while the 4 Threads run and increment their counters.Once the Main thread is revived the program terminates after printing the final count values.

What I got as output was something like this:

Job 1: 5876

Job 2: 6546

Job 3: 6020

Job 4: 0

Even though the thread running job 4 got highest priority.

I think I have some serious conceptual problem here...And maybe what I am trying to do is not what I am doing in the program. Please help me. Thank you in Advance.

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);

    }

}

Your benchmark has several big problems.

  1. Threads don't start running at the same time. Starting a thread is a costly operation, and by the time you're starting the 4th thread, the first one has already had the time to count. You should use a CountDownLatch to make sure all threads start counting (approximately) at the same time.
  2. You're accessing a variable written by each thread from the main thread without any kind of synchronization. So the main thread could see a value that isn't the actual value of the counter. You need to make the count variable volatile, or to use an AtomicInteger.
  3. You don't let enough time to the threads. For example, your main thread prints the value of the last started thread before it has even had a chance to start executing. You need to give the scheduler some time to schedule each thread and apply the priorities.
  4. I don't know how many cores you have. But if you have 4 of them, every thread might run on its own core, and the priorities wouldn't be used at all, since they don't fight each other to get some CPU time. Use more threads, so that you actually have some contention.

Better use a lock inside the task were all Threads must wait for a start signal. Otherwise you cant ensure they start parallel. Here is a simple soulution using a CountDownLatch which ensures that all tas start at the same time.

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);

    }

Your threads execute for a very short span of time. If you execute them longer, there is a chance that you might see more count in higher priority thread. Even then main thing is that there is no guarantee by JVM that this difference in count will be visible in the time your program runs. If your functionality depends on one thread to finish before other, explore Thread join . However, in your particular case join won't work because Threads are running in infinite loop

The Java API states:

Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.

However, if thread priorities will be taken into consideration depends on the scheduling algorithm which might differ between operating systems, versions of the same operating system, or different JVMs. Thereby it is considered a bad practice to rely on thread priorities for your java program's correctness, as this could lead to unexpected behaviour if run on different OS or different JVM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM