Java 虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中线程式的优先级相同,那么就随
机选择一个线程,使其占用CPU.处于运行状态的线程式会一直运行,直到它不得不放弃CPU.
值得注意的是,线程的调度不是跨平台的,它不仅取决于Java虚拟机,还依赖于操作系统.在某些系统中,只要运行中的线程没有遇到
阻塞,就不会放弃CPU;在某些系统中,即使运行中的线程没有遇到阻塞,也会在运行一定时间后放弃CPU,给其他线程运行的机会.
如果希望明确地让一个线程给另一个线程运行的机会,可以采取以下方法之一:
1.调整各个线程的优先级.
2.让处于运行状态的线程调用Thread.sleep()方法.
3.让处于运行状态的线程调用Thread.yield()方法.
4.让处于运行状态的线程调用另一个线程的join()方法.
值得注意的是,尽管Java提供了10个优先级,但它与多数操作系统都不能很好地映射.比如Windows 2000有7个优先级,并且不是固定
的,而SUN公司的Solaris操作系统有2的31次方个优先级.如果希望程序能移植到不同的平台中,应该确保在设置线程的优先级时,只使
用MAX_PRIORITY.NORM_PRIORITY.MIN_PRIORITY这三个优先级.这样才能保证在不同的操作系统中,对同样优先级的线程式采用同样的
调试方式.
一个线程创A建了另一个线程B,则线程B的优先级就和线程A的优先级是一样的,比如主线程创建了另一个线程,则这个被创建的线程
式的优先级就和主线程的优先级是一样的.
下面是一个例子:
public class Machine extends Thread{
public void run()
{
for(int a=0;a<3;a++)
{
System.out.println(currentThread().getName()+":"+a);
/*if(a==1 && currentThread().getName().equals("m1"))
throw new RuntimeException("Wrong from Machine");
try
{
sleep(100);
}
catch(InterruptedException e)
{
throw new RuntimeException(e);
}*/
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Machine m=new Machine();
m.setName("m1");
Thread main=Thread.currentThread();
System.out.println("the main thread's priority is:"+main.getPriority());
m.start();
System.out.println("the default priority is:"+m.getPriority());
m.setPriority(MIN_PRIORITY);
System.out.println("the min priority is:"+m.getPriority());
//m.run();
//System.out.println("Is machine alive "+m.isAlive());
//System.out.println("main:end");
}
}
线程中sleep()方法和yeild()方法的主要区别:
1.sleep()方法会给其他线程运行的机会,而不管其他线程的优先级,因此会给较低优先级的线程运行的机会;yeild()方法只会给优先
级相同的或者比自己高的线程运行的机会.
2.sleep()方法声明抛出InterruptionException异常,而yeild()方法没有声明抛出任何异常.
3.sleep()方法比yeild()方法具有更高的可移植性.
4.sleep()方法使线程进入阻塞状态,而yeild()方法使线程进入就绪状态.
当前运行的线程可以调用另一个线程的join()方法,当前运行的线程将转到阻塞状态,直到另一个线程运行结束,它才会恢复运行.
join()有两种形式:public void join()和public void join(long timeout)可以设置阻塞的时间.
使用setDaemon()方法可以将线程设置成后台线程,使用isDaemon()方法则可以判断线程是否是后台线程.
使用后台线程应该注意:
1. Java虚拟机只保证当前所有前台线程结束时,所有后台线程也会结束,而不保证后台线程一定是在前台线程结束后结束.
2.只有在线程启动前(即调用start()方法前),才能把它设置成后台线程.如果线程启动后,再调用这个线程的setDaemon()方法,则会抛
出异常.
3.由前台线程创建的线程在默认情况下仍然的前台线程,由后台线程创建的线程仍然是后台线程.
机选择一个线程,使其占用CPU.处于运行状态的线程式会一直运行,直到它不得不放弃CPU.
值得注意的是,线程的调度不是跨平台的,它不仅取决于Java虚拟机,还依赖于操作系统.在某些系统中,只要运行中的线程没有遇到
阻塞,就不会放弃CPU;在某些系统中,即使运行中的线程没有遇到阻塞,也会在运行一定时间后放弃CPU,给其他线程运行的机会.
如果希望明确地让一个线程给另一个线程运行的机会,可以采取以下方法之一:
1.调整各个线程的优先级.
2.让处于运行状态的线程调用Thread.sleep()方法.
3.让处于运行状态的线程调用Thread.yield()方法.
4.让处于运行状态的线程调用另一个线程的join()方法.
值得注意的是,尽管Java提供了10个优先级,但它与多数操作系统都不能很好地映射.比如Windows 2000有7个优先级,并且不是固定
的,而SUN公司的Solaris操作系统有2的31次方个优先级.如果希望程序能移植到不同的平台中,应该确保在设置线程的优先级时,只使
用MAX_PRIORITY.NORM_PRIORITY.MIN_PRIORITY这三个优先级.这样才能保证在不同的操作系统中,对同样优先级的线程式采用同样的
调试方式.
一个线程创A建了另一个线程B,则线程B的优先级就和线程A的优先级是一样的,比如主线程创建了另一个线程,则这个被创建的线程
式的优先级就和主线程的优先级是一样的.
下面是一个例子:
public class Machine extends Thread{
public void run()
{
for(int a=0;a<3;a++)
{
System.out.println(currentThread().getName()+":"+a);
/*if(a==1 && currentThread().getName().equals("m1"))
throw new RuntimeException("Wrong from Machine");
try
{
sleep(100);
}
catch(InterruptedException e)
{
throw new RuntimeException(e);
}*/
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Machine m=new Machine();
m.setName("m1");
Thread main=Thread.currentThread();
System.out.println("the main thread's priority is:"+main.getPriority());
m.start();
System.out.println("the default priority is:"+m.getPriority());
m.setPriority(MIN_PRIORITY);
System.out.println("the min priority is:"+m.getPriority());
//m.run();
//System.out.println("Is machine alive "+m.isAlive());
//System.out.println("main:end");
}
}
线程中sleep()方法和yeild()方法的主要区别:
1.sleep()方法会给其他线程运行的机会,而不管其他线程的优先级,因此会给较低优先级的线程运行的机会;yeild()方法只会给优先
级相同的或者比自己高的线程运行的机会.
2.sleep()方法声明抛出InterruptionException异常,而yeild()方法没有声明抛出任何异常.
3.sleep()方法比yeild()方法具有更高的可移植性.
4.sleep()方法使线程进入阻塞状态,而yeild()方法使线程进入就绪状态.
当前运行的线程可以调用另一个线程的join()方法,当前运行的线程将转到阻塞状态,直到另一个线程运行结束,它才会恢复运行.
join()有两种形式:public void join()和public void join(long timeout)可以设置阻塞的时间.
使用setDaemon()方法可以将线程设置成后台线程,使用isDaemon()方法则可以判断线程是否是后台线程.
使用后台线程应该注意:
1. Java虚拟机只保证当前所有前台线程结束时,所有后台线程也会结束,而不保证后台线程一定是在前台线程结束后结束.
2.只有在线程启动前(即调用start()方法前),才能把它设置成后台线程.如果线程启动后,再调用这个线程的setDaemon()方法,则会抛
出异常.
3.由前台线程创建的线程在默认情况下仍然的前台线程,由后台线程创建的线程仍然是后台线程.
3635





