您的位置:首页 > 编程语言 > Java开发

Java中yield()和join()在线程中的不同

2015-12-02 20:58 337 查看
对线程优先级的理解

对线程的优先级的理解对于多线程的学习和yield()工作原理的理解非常有帮助。

1、如果没有具体指定优先级,那么所有线程优先级都属于普通优先级。

2、优先级分为1到10这十个等级,其中10是最高优先级,1是最低优先级,5属于普通优先级。

3、具有最高优先级的线程将会优先被执行,但是这并不能保证它在启动的时候就是运行状态。

4、对于在线程池中等待被调度的线程来说,当前执行的线程可能有更高的优先级。

5、决定哪个线程应该被执行的是线程调度者。

6、t.setPriority()方法可以用于设置线程的优先级。

7、线程的优先级应该在线程的start方法调用之前被设置。

8、可以使用常量MIN_PRIORITY,MAX_PRIORITY 和 NORM_PRIORITY来设置优先级。

yield()方法

调用yield方法就是表示线程告诉虚拟机,它愿意让其他的线程在这个地方被调度,也就是它可以让出当前执行的时间片,但它并不会使当前线程阻塞,下个时间片它可能会被继续执行,这表明该线程没有在做一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。

下面是yield()在Thread.java中的定义

/**
* A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore
* this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU.
* Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.
*/

public static native void yield();


下面有重要的几点:

1、Yield是一个静态的原生(native)方法

2、Yield 告诉当前执行的线程可以给一个机会给线程池中有相同优先级的线程,让它们被调度。

3、Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态

4、它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态

在下面的示例程序中,我随意的创建了名为生产者和消费者的两个线程。生产者设定为最小优先级,消费者设定为最高优先级。在Thread.yield()注释和非注释的情况下我将分别运行该程序。没有调用yield()方法时,虽然输出有时改变,但是通常消费者行先打印出来,然后事生产者。

package test.core.threads;

public class YieldExample
{
public static void main(String[] args)
{
Thread producer = new Producer();
Thread consumer = new Consumer();

producer.setPriority(Thread.MIN_PRIORITY); //Min Priority
consumer.setPriority(Thread.MAX_PRIORITY); //Max Priority

producer.start();
consumer.start();
}
}

class Producer extends Thread
{
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Producer : Produced Item " + i);
Thread.yield();
}
}
}

class Consumer extends Thread
{
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Consumer : Consumed Item " + i);
Thread.yield();
}
}
}


没有yield()方法时的输出结果:

I am Consumer : Consumed Item 0
I am Consumer : Consumed Item 1
I am Consumer : Consumed Item 2
I am Consumer : Consumed Item 3
I am Consumer : Consumed Item 4
I am Producer : Produced Item 0
I am Producer : Produced Item 1
I am Producer : Produced Item 2
I am Producer : Produced Item 3
I am Producer : Produced Item 4


有yield()方法时的输出结果:

I am Producer : Produced Item 0
I am Consumer : Consumed Item 0
I am Producer : Produced Item 1
I am Consumer : Consumed Item 1
I am Producer : Produced Item 2
I am Consumer : Consumed Item 2
I am Producer : Produced Item 3
I am Consumer : Consumed Item 3
I am Producer : Produced Item 4
I am Consumer : Consumed Item 4


join()方法

一个线程实例的join方法可以将一个线程的执行加入到另一个线程中,使得只有加入的线程执行完毕之后,当前线程才能进行运行。如果join方法被一个实例线程调用,那么当前线程就会处于阻塞状态,直到这个实例线程执行完毕。

//Waits for this thread to die.

public final void join() throws InterruptedException


在join()方法内设定超时,使得join()方法的影响在特定超时后无效。当超时时,主方法和任务线程申请运行的时候是平等的。然而,当涉及sleep时,join()方法依靠操作系统计时,所以你不应该假定join()方法将会等待你指定的时间。

package test.core.threads;

public class JoinExample
{
public static void main(String[] args) throws InterruptedException
{
Thread t = new Thread(new Runnable()
{
public void run()
{
System.out.println("First task started");
System.out.println("Sleeping for 2 seconds");
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("First task completed");
}
});
Thread t1 = new Thread(new Runnable()
{
public void run()
{
System.out.println("Second task completed");
}
});
t.start(); // Line 15
t.join(); // Line 16
t1.start();
}
}


输出结果:

First task started
Sleeping for 2 seconds
First task completed
Second task completed


原文链接:Difference between yield() and join() in threads in java?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: