多线程之常用函数
来源:互联网 发布:linux配置ftp 编辑:程序博客网 时间:2024/06/05 06:02
1.0 sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠
2.0 join():指等待t线程终止
join是Thread类的一个方法,启动线程后直接调用,即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
为什么要用join()方法
在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。
例子:
package com.xiaohao.thread;public class TestJoin implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stubfor(int i=0;i<5;i++) {System.out.println(Thread.currentThread().getName() + " 线程在运行");try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(Thread.currentThread().getName() + " 线程已结束");}}
测试代码:
package com.xiaohao.test;import java.util.concurrent.CountDownLatch;import org.junit.Test;import com.xiaohao.thread.TestJoin;public class JoinTest {private CountDownLatch latch = new CountDownLatch(10);/** * 没有加入join时,main线程不会等待t线程执行完,会事先执行完 */@Testpublic void testJoin01() {System.out.println(Thread.currentThread().getName() + "主线程开始了");Thread t = new Thread(new TestJoin());t.start();System.out.println(Thread.currentThread().getName() + "主线程结束了");try {latch.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 1.0 如果使用t.join()的话,main线程会等待t运行完之后,再执行后面的代码 * 2.0 如果使用t.join(1000)的话,面线程会等待t执行1s后,在执行后面的代码 */@Testpublic void testJoin02() {System.out.println(Thread.currentThread().getName() + "主线程开始了");Thread t = new Thread(new TestJoin());t.start();try {t.join(1000);} catch (InterruptedException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}System.out.println(Thread.currentThread().getName() + "主线程结束了");try {latch.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
testJoin01 output:
main主线程开始了
main主线程结束了
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程已结束
testJoin02
main主线程开始了
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程在运行
Thread-0 线程已结束
main主线程结束了
3.0 yield():暂停当前正在执行的线程对象,并执行其他线程
sleep()和yield()的区别):sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,yield 方法使当前线程让出 CPU 占有权,但让出的时间是不可设定的。实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU 的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程
另外,sleep 方法允许较低优先级的线程获得运行机会,但 yield() 方法执行时,当前线程仍处在可运行状态,所以,不可能让出较低优先级的线程些时获得 CPU 占有权。在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I\O 阻塞,那么,较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。
共同点:
1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep /join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
不同点:
1. Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等
2. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
所以sleep()和wait()方法的最大区别是:
sleep()睡眠时,保持对象锁,仍然占有该锁;
而wait()睡眠时,释放对象锁。
但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。
sleep()方法
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
wait()方法
wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。
线程类的一些常用方法:
sleep(): 强迫一个线程睡眠N毫秒。
isAlive(): 判断一个线程是否存活。
join(): 等待线程终止。
activeCount(): 程序中活跃的线程数。
enumerate(): 枚举程序中的线程。
currentThread(): 得到当前线程。
isDaemon(): 一个线程是否为守护线程。
setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
setName(): 为线程设置一个名称。
wait(): 强迫一个线程等待。
notify(): 通知一个线程继续运行。
setPriority(): 设置一个线程的优先级。
- 多线程之常用函数
- 六.java多线程之常用函数理解
- Linux常用多线程函数
- 多线程之常用api
- Windows下多线程常用函数
- Windows下多线程常用函数
- 网络多线程-GCD常用函数
- 多线程之线程常用操作方法
- Java多线程之常用方法
- JAVA多线程之常用方法
- 常用oracle之常用函数
- ExtJs4之常用函数
- MYSQL之常用函数
- Hive 之 常用函数
- 【无聊时作】多线程常用函数
- c++ 多线程编程常用的几个函数
- c++ 多线程编程常用的几个函数
- 多线程基本步骤及常用函数
- Openwrt开发日志——iptables的各个…
- Openwrt开发日志——iptables对报文处理
- Winform实现后台推送,数据跨线程实时刷新控件
- adaboost学习(一)
- oracle 12c静默安装 Linux Oracle安装遇到的问题
- 多线程之常用函数
- css+js简单实现table固定首行首列
- 应用不相交集类生成迷宫
- 全面理解控制反转和依赖注入
- [kotlin系列] (s2_3)扩展、数据类、密封类
- Guass-newton
- 信息滚动效果制作
- WebService动态IP调用
- bugku SQL注入测试