- 1、线程的状态:
- 2、BLOCKED 和 WAITING 的区别
- 3、线程优先级
- 4、线程的常用方法
- 1、wait()
- 2、join()
- 3、yield()
- 4、sleep()
线程(Thread)是并发编程的基础,也是程序执行的最小单元。
一个进程中可以包含多个线程;
多个线程可以共享一块内存空间和一组系统资源。
线程之间奇幻更加轻量化和节省资源
1、线程的状态:- NEW:新建状态,线程被创建出来,但尚未启动时的线程状态
- RUNNABLE:就绪状态,表示可以运行的线程状态,它可能正在运行,或者是在排队等待 *** 作系统给它分配 CPU 资源;
- BLOCKED:阻塞等待锁的线程状态,表示处于阻塞状态的线程正在等待监视器锁,比如等待执行 synchronized 代码块或者使用 synchronized 标记的方法;
- WAITING:等待状态,一个处于等待状态的线程正在等待另一个线程执行某个特定的动作,比如,一个线程调用了 Object.wait() 方法,那它就在等待另一个线程调用 Object.notify() 或 Object.notifyAll() 方法;
- TIMED_WAITING:计时等待状态,和等待状态(WAITING)类似,它只是多了超时时间,比如调用了有超时时间设置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等这些方法时,它才会进入此状态;
- TERMINATED,计时等待状态,和等待状态(WAITING)类似,它只是多了超时时间,比如调用了有超时时间设置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等这些方法时,它才会进入此状态;终止状态,表示线程已经执行完成。
虽然 BLOCKED 和 WAITING 都有等待的意思,但二者有着本质的区别,首
先它们状态形成的调用方法不同,其次 BLOCKED 可以理解为当前线程还处于活跃状态,只是在阻塞等待其他线程使用完某个锁资源;而 WAITING 则是因为自身调用了 Object.wait() 或着是 Thread.join() 又或者是 LockSupport.park() 而进入等待状态,只能等待其他线程执行某个特定的动作才能被继续唤醒,比如当线程因为调用了 Object.wait() 而进入 WAITING 状态之后,则需要等待另一个线程执行 Object.notify() 或 Object.notifyAll() 才能被唤醒。
3、线程优先级//在 Thread 源码中和线程优先级相关的属性有 3 个: // 线程可以拥有的最小优先级 public final static int MIN_PRIORITY = 1; // 线程默认优先级 public final static int NORM_PRIORITY = 5; // 线程可以拥有的最大优先级 public final static int MAX_PRIORITY = 10
线程的优先级可以理解为线程抢占 CPU 的概率,优先级越高的线程优先执行的概率就越大,但并不能保证优先级高的线程一定先执行。
在程序中我们可以通过 Thread.setPriority() 来设置优先级,setPriority() 源码如下:
public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); // 先验证优先级的合理性 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { // 优先级如果超过线程组的最高优先级,则把优先级设置为线程组的最高优先级 if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); } }4、线程的常用方法 1、wait()
wait方法是Object对象的方法
wait方法会将当前线程放入wait set,等待被唤醒,并放弃lock对象上的所有同步声明,当前线程会因为线程调度的原因处于休眠状态而不可用。只有通过以下四个方法可以主动唤醒:
-
notify
-
notifyAll
-
Thread.interrupt()
-
等待时间过完。
在一个线程中调用 other.join() ,这时候当前线程会让出执行权给 other 线程,直到 other 线程执行完或者过了超时时间之后再继续执行当前线程,join() 源码如下:
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; // 超时时间不能小于 0 if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } // 等于 0 表示无限等待,直到线程执行完为之 if (millis == 0) { // 判断子线程 (其他线程) 为活跃线程,则一直等待 while (isAlive()) { wait(0); } } else { // 循环判断 while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
从源码中可以看出 join() 方法底层还是通过 wait() 方法来实现的。
3、yield()yield会释放CPU资源,它会使调用线程放弃CPU使用权,加入到同等优先级队列的末尾,让优先级更高(至少是相同)的线程获得执行机会;
如果调用线程是优先级最高的唯一线程,yield方法返回后,调用线程会继续运行;
sleep当传入参数为0时,和yield相同;当传入参数大于0时,也是释放CPU资源,当可以让其它任何优先级的线程获得执行机会;
假设当前进程只有main线程,当调用yield之后,main线程会继续运行,因为没有比它优先级更高的线程;而调用sleep之后,mian线程会进入TIMED_WAITING状态,不会继续运行;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)