看下面的代码例子,请问程序的输出结果是5吗?,按照我们常规的想法,结果应该是5,而实际答案是有可能是5,也有可能是0,并且很难遇到是5的情况(这与机器的性能有很大关系),为什么大部分情况是0?那是因为当我们执行语句时,这是同时有main线程和th线程,他们的优先级是相同的,当main线程先抢到CPU控制权时,sum的值还没变还是0,如果t先抢到CPU控制权,sum的值就是5
package thread;
/**
*
* @author liyu2
* 测试线程调度
*/
public class TestDispatch implements Runnable {
public static int sum =0;
public static void main(String[] args) {
Runnable r = new TestDispatch();
Thread th =new Thread(r);
th.start();
System.out.println("sum=" + sum);
}
@Override
public void run() {
for(int i=0; i<5 ;i++){
sum += 1;
}
}
}
那么我们怎样可以让他输出5呢,这里我们就要用到线程的调度
java总有四种调度的方法
(1):设置线程的优先级
package thread;
/**
*
* @author liyu2
* 测试线程调度
*/
public class TestDispatch implements Runnable {
public static int sum =0;
public static void main(String[] args) {
Runnable r = new TestDispatch();
Thread th =new Thread(r);
//建议只使用Thread类中的三个常量域
//Thread.MAX_PRIORITY ,Thread.NORM_PRIORITY,Thread.MIN_PRIORITY
th.setPriority(Thread.MAX_PRIORITY);
th.start();
System.out.println("sum=" + sum);
}
@Override
public void run() {
for(int i=0; i<5 ;i++){
sum += 1;
}
}
}
(2):Join()方法的应用
调用th.join()方法会使当前运行的线程将CPU控制权交出,接着运行线程th,线程th运行完毕后,main线程接着运行
package thread;
/**
*
* @author liyu2
* 测试线程调度
*/
public class TestDispatch implements Runnable {
public static int sum =0;
public static void main(String[] args) throws InterruptedException {
Runnable r = new TestDispatch();
Thread th =new Thread(r);
th.start();
// 调用th.join()方法会使当前运行的线程将CPU控制权交出,接着运行线程th,线程th运行完毕后
//main线程接着运行
th.join();
System.out.println("sum=" + sum);
}
@Override
public void run() {
for(int i=0; i<5 ;i++){
sum += 1;
}
}
}
(三):sleep()方法的应用
sleep()方法是静态方法,通过类名Thread直接调用,调用该方法会使当前正在运行的线程暂停执行一定的时间,这样会让出CPU控制权,给其他的线程运行机会,
下面的代码先让正在运行的线程main休眠2秒钟,给th线程先运行的机会
package thread;
/**
*
* @author liyu2
* 测试线程调度
*/
public class TestDispatch implements Runnable {
public static int sum =0;
public static void main(String[] args) throws InterruptedException {
Thread.sleep(2000);
Runnable r = new TestDispatch();
Thread th =new Thread(r);
th.start();
System.out.println("sum=" + sum);
}
@Override
public void run() {
for(int i=0; i<5 ;i++){
sum += 1;
}
}
}
(四):yield()方法的应用
package thread;
public class YieldThread implements Runnable {
@SuppressWarnings("static-access")
@Override
public void run() {
for(int i= 0; i<5; i++){
System.out.println(Thread.currentThread().getName());
//Thread.currentThread().yield();
}
}
public static void main(String[] args) {
YieldThread yth = new YieldThread();
Thread th1 = new Thread(yth,"线程1");
Thread th2 = new Thread(yth,"线程2");
Thread th3 = new Thread(yth,"线程3");
th1.setPriority(5);
th2.setPriority(10);
th3.setPriority(5);
th1.start();
th2.start();
th3.start();
System.out.println("main方法最后一句");
}
}
区别:
sleep() :方法使线程休眠一段时间,这段时间结束后,线程进入就绪状态,但并不是立即执行,只有被分配到CPU控制权时才执行
join() :CPU控制权先给join进来的线程,直到它结束,原线程才会继续执行
yield():让当前运行线程让出CPU控制权,给其他线程机会,但是yield()方法使现象放弃执行的权利后,进入就绪状态,也就意味着线程在yield()方法后,有可能又执行,并且yield()方法只给相同优先级或者比自己优先级高的线程机会