一.sleep()方法
首先在Thead类中有一个静态的sleep()方法,可以让线程进入到休眠状态即TEMD-WAITING状
在调用sleep()方法时需要注意的是在哪个线程里面调用sleep()方法,哪个线程就会进入阻塞状态.,在这个线程中的其他线程不会发生阻塞, 只有当休眠时间到来这个线程才会继续执行.如
public class Demo5 {
public static void main(String[] args) throws InterruptedException {
MyThread6 myThread6 = new MyThread6();
myThread6.start();
Thread.sleep(10);
System.out.println("mian线程开始工作");
}
}
class MyThread6 extends Thread{
@Override
public void run() {
System.out.println("创建的线程名是 " + Thread.currentThread().getName());
}
}
在main方法中创建一个线程myThread6这个对象 并调用start()方法启动线程执行run()方法,然后Thread.sleep(10)会让main主线程进入休眠状态,休眠10毫秒后才会继续执行,打印输出.
sleep()方法是知道要等待的时间是多少,才会调用sleep()方法.让这个线程进入休眠其他线程去执行.这样就影响了线程间的执行顺序.总的来说调用sleep()是有规划时间的让一个线程进入休眠,让其他下次线程先执行,等过了休眠时间这个线程再去执行.
二join()方法.
1.线程对象.join()
在多进程中,多个线程的执行顺序是无序的(因为线程的调度是"随即调度" 并且是"抢占式执行"的)虽然线程的调度是无序的,但操作系统的api 提供了一些方法可以影响线程的执行顺序 ,而这些api通过JVM又封装了一层.这些api有 Thread类中的sleep(),join()方法等.
join()方法是让一个线程等待另一个线程执行完后才会继续执行,如让线程2 等待线程1结束,线程1结束之后线程2才会继续执行.
在哪个线程里一个线程对象调用join(),哪个线程就阻塞,等待调用join()方法的线程结束,才会继续执行.
为什么不用sleep()方法呢?用sleep()方法需要知道休眠的时间即要等待的线程还要多长时间结束,如果不确定自己预估一个时间可能,预估的少了,等待的线程还没结束,预估的多了,又多等了很长时间.
.这样就影响了线程结束的先后顺序.举个例子吧
public class Demo5 {
public static void main(String[] args) throws InterruptedException {
MyThread6 myThread6 = new MyThread6();
myThread6.start();
myThread6.join();
System.out.println("mian线程开始工作");
}
}
class MyThread6 extends Thread{
@Override
public void run() {
while(true){
System.out.println("创建的线程在执行");
}
}
}
如在main()方法中myThread6调用join()方法,让main线程等待myThread6线程结束,main线程才会继续执行.在哪个线程中调用join()方法,哪个线程就阻塞,等待调用join()方法的线程执行完,这个阻塞线程才会转换成可执行状态等待cpu的调度继续执行.
上述线程结束顺序的先后通过调用join()即系统提供的api来控制
join()方法 主要是 1)让main线程主动放弃cpu的调度,进入阻塞状态,
2)等待调用join()方法的那个线程结束,才会进入可执行状态等待cpu的调度
2.线程对象.join(时间)
join(时间) 是带有时间的等待,因为调用join()的线程可能一直在运行如"死循环",等待的线程一直会处于阻塞状态,永远也不会执行,这是就会设置一个时间,超过这个等待时间后就不继续往下等了,恢复成可执行的状态等待cpu的调度.
join(时间) 与sleep(时间)区别:
sleep(时间) 是提前知道了要让一个线程休眠的时间,休眠时间一到,线程就会继续执行.
而join(时间) 是一个线程等待另一个线程结束,因某种原因被等待的线程不能结束一直在运行,join(时间)的这个时间就是保底的,不让等待的线程一直死等下去,只要过了这个时间不管被等待的线程有没有执行完,都不会继续等待下去,会回去执行自己的任务.
三.线程的六种状态.
1. NEW 状态
处于NEW状态的线程此时尚未启动,这里的尚未启动这是还没开始调用start()方法的状态.如:
在上一篇也讲过,处于NEW状态的线程才能调用start()方法,因为处于NEW状态时Thread类中的threadStatus = 0 才能调用本地方法start0()才能真正地创建其启动线程,处于其他状态时threadStatus 是不为0的,threadStatus使用整数来表示线程的状态的.
2.RUNNABLE状态
表示当前线程正在执行,处于RUNNABLE状态的线程可能在JVM中运行,也有可能等待cpu分配资源也就是说RUNNABLE状态包含了ready和running两种状态.在进程中就是就绪状态和执行状态这两种.
3.BLOCKED状态:
阻塞状态.处于BLOCKED状态的线程是在等待锁的释放也可以理解位要访问的资源正在被其他线程所占用,等待这个线程释放这个资源.
4.WAITING状态:
等待状态. 处于等待状态的线程需要其他线程进行唤醒.
一般有三种方法会使进程进入等待状态,不过第三种是LockSupport等后面在详细讲讲.
1)Object.wait() .使当前处于等待状态等待另一个线程唤醒它.
2)Thread.join() 等待某个线程执行完毕后,这个线程才能执行.底层调用的是Object.wait()方法
5.TIMED_WAITING状态
超时等待状态.线程等待一个具体的时间,时间过后会自动唤醒.
有3中方式可以进入超时等待状态:
1) Object.wait(long millis): 线程休眠指定时间,等待期间可以被notify()或notifyAll()唤醒.
2)Thread.sleep(long millis):使当前线程睡眠指定的时间.
3)Thread.join(long millis): 等待某个线程最多 millis毫秒.
6.TEMINATED状态.
执行完毕状态.线程执行完run()方法了.