线程的创建
1:继承Thread类
2:实现Runnable接口
3:实现Cellable接口
具体创建在栗子中讲解
Thread类的静态工厂方法——sleep()
public static void sleep(long millis) throws InterruptedException{
......
}
使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
参数
millis - 以毫秒为单位的睡眠时间长度
异常
IllegalArgumentException - 如果 millis值为负数
InterruptedException - 如果任何线程中断当前线程。 当抛出此异常时,当前线程的中断状态将被清除。
public static void sleep(long millis,int nanos) throws InterruptedException{
...
}
导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(临时停止执行),这取决于系统定时器和调度器的精度和准确性。
参数
millis - 以毫秒为单位的睡眠时间长度
nanos - 0-999999额外的纳秒睡眠
异常
IllegalArgumentException -如果值 millis为复数,或的值 nanos不在范围 0-999999
InterruptedException - 如果任何线程中断当前线程。 当抛出此异常时,当前线程的中断状态将被清除。
/**
*
* @author Change
* 线程的生命周期
* 1:新建状态
* 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态,不能对已经启动的线程再次调用start()方法
*
* 2:就绪状态
* 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(可运行池)
*
* 3:运行状态
* 处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务
*
* 4:阻塞状态
* wait(objict方法),会进入等待队列,一般在消费者生产者问题中出现
* 当发生如下情况是,线程会从运行状态变为阻塞状态:
①、线程调用sleep方法主动放弃所占用的系统资源
②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞
③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有
④、线程在等待某个通知(notify)
*
* 5:死亡状态
* 当线程的run()方法执行完,或者被强制性地终止,就认为它死去
*
*/
public class ThreadSleepDemo {
public static void main(String[] args) throws InterruptedException {
//1、线程睡眠——sleep 需要让当前正在执行的线程暂停一段时间,并进入阻塞状态
//sleep是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,
Thread t = new myThread();
t.start();
t.sleep(5000); //睡眠的始终是当前正在运行的线程,而不是调用它的对象的线程
Thread.sleep(5000);
System.out.println("主线程");
}
}
class myThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
System.out.println("这是另一个线程");
}
}
你能说出代码中两行输出的打印顺序与间隔时间吗?
Thread类的静态工厂方法——yield()
public static void yield(){
...
}
对调度程序的一个暗示,即当前线程愿意自动让出当前使用的处理器。 调度程序可以自由地忽略这个提示。
这个栗子没有多大的意义 ,因为现在计算机大多都是多核处理器(上篇博文有提到),且操作系统是基于线程进行调度的,所以当前线程是否让步、是否让出处理本线程的处理器使用权限,与其他线程没有根本的关系
你只需要清楚:yield()让出cpu资源给其他的线程。但是和sleep()方法不同的是,它不会进入到阻塞状态,而是进入到就绪状态(进入可运行池)
/**
* @author Administrator
*线程让步——yield
*yield()方法和sleep()方法有点相似,它也是Thread类提供的一个静态的方法,它也可以让当前正在执行的线程暂停,
*让出cpu资源给其他的线程。但是和sleep()方法不同的是,它不会进入到阻塞状态,而是进入到就绪状态(进入可运行池)
*/
public class ThreadYieldDemo {
public static void main(String[] args) {
Thread t1 = new myThread1();
Thread t2 = new myThread1();
t1.start();
t2.start();
}
}
class myThread1 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(int i =0;i < 30; i++) {
System.out.println(this.getName()+"线程第"+i+"次运行");
if(i%5==0) {
Thread.yield();
}
}
}
}