多线程实现的细节---sleep和wait方法的区别、如何停止线程(interrupt方法)、守护线程(setDaemon())、join()方法、toString()方法、优先级、yield()方法
1.sleep和wait有什么区别?
sleep方法必须制定时间;wait方法有重载形式,可以指定时间,也可以不指定时间。
- sleep方法
static void sleep(long millis):在执行的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
static void sleep(long millis,int nanos):在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
- wait方法
wait()---在其他线程调用此对象的notify()方法活notifyAll()方法之前,导致当前线程等待。
wait(long timeout)-----在其他线程调用此对象的notify()方法活超过指定的时间量前,导致当前线程等待。
wait(long timeout,int nanos)------在其他线程调用此线程的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
对于执行权和锁的操作
- sleep():
释放执行权,因为如果不释放执行权,CPU只会处理当前休眠的线程,不能达到多线程操作的目的;
不释放锁:因为线程肯定能唤醒,肯定可以恢复到临时阻塞状态。
- wait()
释放执行权;
释放锁:因为如果一个线程进入wait方法后不释放锁,如果没有时间指定,那么其他线程都进行不了同步中,无法将其唤醒。
同步中可以有多个存活的线程,但是只能有一个执行同步的代码。因为只有一个线程会持有同步的锁。
只有当该线程释放了锁,其他线程才有机会获取到锁,只能一个线程能够获取到锁,继续执行。
public synchronized void show() { if() wait(); code....; notify(); code....; }
例如线程A 进入同步方法,执行逻辑判断之后,wait()之后进入等待冻结状态,释放锁,释放执行权;只有释放锁,线程B才可以获取到锁进入同步方法show()中,线程B执行notify()之后,线程A被激活;此时存活的线程有线程A和线程B,但是只有线程B持有锁,所以只有线程B持有锁,只有线程B有CPU的执行权,所以只有线程B 会执行,只有当线程B执行wait()释放锁之后,线程A才会获得锁,才会进行执行。
如何让线程停止
停止线程有两种方式:
1.使用Thread类中的stop方法,但是该方法已经过时了。
2.线程执行的代码结束,也就是run方法执行结束
通常定义线程代码都有循环,因为需要单独开辟一个执行路径去重复很多事情,既然有循环,只要控制住循环,就可以结束run方法。
package Test.Test; public class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=1; while(true){ if(num++==5000){ st.setFlag(); break; } System.out.println(Thread.currentThread().getName()+"--------"+num); } } } class StopThread implements Runnable{ private boolean flag=true; @Override public synchronized void run() { while(flag){ System.out.println(Thread.currentThread().getName()+"------"); } } public void setFlag() { this.flag = false; } }
代码中开启了三个线程,当主线程执行num为500时,设置st的flag属性为false,主线程结束,两个子线程判断flag为false,run方法结束,两个子线程结束。
interrupt方法
定义标记可以结束循环进而结束线程,但是如果子线程在运行过程中存储了冻结状态,没有执行到标记,这时子线程不能够正常结束,可以通过Thread类的interrupt方法中断线程的冻结状态,强制让其恢复到运行状态中来,就可以有机会执行标记,但是这种强制动作会发生InterruptedException异常,可以在catch住异常之后在异常处理块中修改标记,使子线程可以执行。
package Test.Test; public class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=1; while(true){ if(num++==5000){ t1.interrupt(); t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+"--------"+num); } } } class StopThread implements Runnable{ private boolean flag=true; @Override public synchronized void run() { while(flag){ try{ wait(); }catch (InterruptedException e){ setFlag(); System.out.println(Thread.currentThread().getName()+".....Exception"); } System.out.println(Thread.currentThread().getName()+"------"); } } public void setFlag() { this.flag = false; } }
守护线程
线程分前台和后台两种,运行方式都一样会获取cpu的执行权执行,不同在于结束方式不同。前台线程只有run方法结束才会结束,后台线程run方法结束会结束,还有一种结束方式是,如果run方法没有结束,而前台线程都结束了,后台线程一样会自动结束。
所以一个进程是否结束参考的是:是否还有前台线程存活,如果前台线程都结束了,那么进程也就结束了。
使用setDaemon(boolean on)如果传入参数为true将创建的线程转化为后台线程,该方法必须在启动线程前调用。
package Test.Test; public class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.setDaemon(true);//将创建的线程转换为后台线程 t2.setDaemon(true); t1.start(); t2.start(); int num=1; while(true){ if(num++==5000){ t1.interrupt(); t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+"--------"+num); } } } class StopThread implements Runnable{ private boolean flag=true; @Override public synchronized void run() { while(flag){ try{ wait(); }catch (InterruptedException e){ setFlag(); System.out.println(Thread.currentThread().getName()+".....Exception"); } System.out.println(Thread.currentThread().getName()+"------"); } } public void setFlag() { this.flag = false; } }
Join方法,临时加入一个线程进行执行
例如:当主线程获取到了cpu的执行权,执行时,执行到了A线程的join方法,这时cpu的执行权在主线程持有,主线程会释放自己的执行权,让A线程进行执行。只有等待A线程执行完以后,主线程才会执行,在A线程执行的过程中主线程处于冻结状态。
一般使用情景:在线程执行过程中,需要一个运算结果时,可以通过加入一个临时线程,将该结果进行运算,这时需要的结果的线程处于冻结状态,等新加入的线程执行完原有的线程才会继续执行。
package Test.Test; public class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); try{ t1.join(); }catch (InterruptedException e){} t2.start(); for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"------"+i); } } } class StopThread implements Runnable{ @Override public synchronized void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"------"+i); } } }
执行结果:主线程执行到t1.join()之后,主线程会让出执行权,直到t1执行完才会继续执行,执行结果如下,不太明白为什么t1和主线程没有抢占CPU执行权。
Thread-0------0 Thread-0------1 Thread-0------2 Thread-0------3 Thread-0------4 Thread-0------5 Thread-0------6 Thread-0------7 Thread-0------8 Thread-0------9 Thread-0------10 Thread-0------11 Thread-0------12 Thread-0------13 Thread-0------14 Thread-0------15 Thread-0------16 Thread-0------17 Thread-0------18 Thread-0------19 Thread-0------20 Thread-0------21 Thread-0------22 Thread-0------23 Thread-0------24 Thread-0------25 Thread-0------26 Thread-0------27 Thread-0------28 Thread-0------29 Thread-0------30 Thread-0------31 Thread-0------32 Thread-0------33 Thread-0------34 Thread-0------35 Thread-0------36 Thread-0------37 Thread-0------38 Thread-0------39 Thread-0------40 Thread-0------41 Thread-0------42 Thread-0------43 Thread-0------44 Thread-0------45 Thread-0------46 Thread-0------47 Thread-0------48 Thread-0------49 Thread-0------50 Thread-0------51 Thread-0------52 Thread-0------53 Thread-0------54 Thread-0------55 Thread-0------56 Thread-0------57 Thread-0------58 Thread-0------59 Thread-0------60 Thread-0------61 Thread-0------62 Thread-0------63 Thread-0------64 Thread-0------65 Thread-0------66 Thread-0------67 Thread-0------68 Thread-0------69 Thread-0------70 Thread-0------71 Thread-0------72 Thread-0------73 Thread-0------74 Thread-0------75 Thread-0------76 Thread-0------77 Thread-0------78 Thread-0------79 Thread-0------80 Thread-0------81 Thread-0------82 Thread-0------83 Thread-0------84 Thread-0------85 Thread-0------86 Thread-0------87 Thread-0------88 Thread-0------89 Thread-0------90 Thread-0------91 Thread-0------92 Thread-0------93 Thread-0------94 Thread-0------95 Thread-0------96 Thread-0------97 Thread-0------98 Thread-0------99 main------0 main------1 main------2 main------3 main------4 main------5 main------6 main------7 main------8 main------9 main------10 main------11 main------12 main------13 main------14 main------15 main------16 main------17 main------18 main------19 main------20 main------21 main------22 main------23 main------24 main------25 main------26 main------27 main------28 main------29 main------30 main------31 main------32 main------33 main------34 main------35 main------36 main------37 main------38 main------39 main------40 main------41 main------42 main------43 main------44 main------45 main------46 main------47 main------48 main------49 main------50 main------51 main------52 main------53 main------54 main------55 main------56 main------57 main------58 main------59 main------60 main------61 main------62 main------63 main------64 main------65 main------66 main------67 main------68 main------69 main------70 main------71 main------72 main------73 main------74 main------75 main------76 main------77 main------78 main------79 main------80 main------81 main------82 main------83 main------84 main------85 main------86 main------87 main------88 main------89 main------90 main------91 main------92 main------93 main------94 main------95 main------96 main------97 main------98 main------99 Thread-1------0 Thread-1------1 Thread-1------2 Thread-1------3 Thread-1------4 Thread-1------5 Thread-1------6 Thread-1------7 Thread-1------8 Thread-1------9 Thread-1------10 Thread-1------11 Thread-1------12 Thread-1------13 Thread-1------14 Thread-1------15 Thread-1------16 Thread-1------17 Thread-1------18 Thread-1------19 Thread-1------20 Thread-1------21 Thread-1------22 Thread-1------23 Thread-1------24 Thread-1------25 Thread-1------26 Thread-1------27 Thread-1------28 Thread-1------29 Thread-1------30 Thread-1------31 Thread-1------32 Thread-1------33 Thread-1------34 Thread-1------35 Thread-1------36 Thread-1------37 Thread-1------38 Thread-1------39 Thread-1------40 Thread-1------41 Thread-1------42 Thread-1------43 Thread-1------44 Thread-1------45 Thread-1------46 Thread-1------47 Thread-1------48 Thread-1------49 Thread-1------50 Thread-1------51 Thread-1------52 Thread-1------53 Thread-1------54 Thread-1------55 Thread-1------56 Thread-1------57 Thread-1------58 Thread-1------59 Thread-1------60 Thread-1------61 Thread-1------62 Thread-1------63 Thread-1------64 Thread-1------65 Thread-1------66 Thread-1------67 Thread-1------68 Thread-1------69 Thread-1------70 Thread-1------71 Thread-1------72 Thread-1------73 Thread-1------74 Thread-1------75 Thread-1------76 Thread-1------77 Thread-1------78 Thread-1------79 Thread-1------80 Thread-1------81 Thread-1------82 Thread-1------83 Thread-1------84 Thread-1------85 Thread-1------86 Thread-1------87 Thread-1------88 Thread-1------89 Thread-1------90 Thread-1------91 Thread-1------92 Thread-1------93 Thread-1------94 Thread-1------95 Thread-1------96 Thread-1------97 Thread-1------98 Thread-1------99
换一种方式:
package Test.Test; public class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); try{ t1.join(); }catch (InterruptedException e){} for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"------"+i); } } } class StopThread implements Runnable{ @Override public synchronized void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"------"+i); } } }
执行结果为:
Thread-0------0 Thread-0------1 Thread-0------2 Thread-0------3 Thread-0------4 Thread-0------5 Thread-0------6 Thread-0------7 Thread-0------8 Thread-0------9 Thread-0------10 Thread-0------11 Thread-0------12 Thread-0------13 Thread-0------14 Thread-0------15 Thread-0------16 Thread-0------17 Thread-0------18 Thread-0------19 Thread-0------20 Thread-0------21 Thread-0------22 Thread-0------23 Thread-0------24 Thread-0------25 Thread-0------26 Thread-0------27 Thread-0------28 Thread-0------29 Thread-0------30 Thread-0------31 Thread-0------32 Thread-0------33 Thread-0------34 Thread-0------35 Thread-0------36 Thread-0------37 Thread-0------38 Thread-0------39 Thread-0------40 Thread-0------41 Thread-0------42 Thread-0------43 Thread-0------44 Thread-0------45 Thread-0------46 Thread-0------47 Thread-0------48 Thread-0------49 Thread-0------50 Thread-0------51 Thread-0------52 Thread-0------53 Thread-0------54 Thread-0------55 Thread-0------56 Thread-0------57 Thread-0------58 Thread-0------59 Thread-0------60 Thread-0------61 Thread-0------62 Thread-0------63 Thread-0------64 Thread-0------65 Thread-0------66 Thread-0------67 Thread-0------68 Thread-0------69 Thread-0------70 Thread-0------71 Thread-0------72 Thread-0------73 Thread-0------74 Thread-0------75 Thread-0------76 Thread-0------77 Thread-0------78 Thread-0------79 Thread-0------80 Thread-0------81 Thread-0------82 Thread-0------83 Thread-0------84 Thread-0------85 Thread-0------86 Thread-0------87 Thread-0------88 Thread-0------89 Thread-0------90 Thread-0------91 Thread-0------92 Thread-0------93 Thread-0------94 Thread-0------95 Thread-0------96 Thread-0------97 Thread-0------98 Thread-0------99 Thread-1------0 Thread-1------1 Thread-1------2 main------0 Thread-1------3 main------1 Thread-1------4 main------2 Thread-1------5 main------3 Thread-1------6 main------4 main------5 Thread-1------7 main------6 Thread-1------8 main------7 Thread-1------9 main------8 Thread-1------10 main------9 Thread-1------11 Thread-1------12 Thread-1------13 main------10 Thread-1------14 main------11 Thread-1------15 main------12 Thread-1------16 main------13 Thread-1------17 main------14 Thread-1------18 main------15 Thread-1------19 main------16 Thread-1------20 Thread-1------21 Thread-1------22 Thread-1------23 Thread-1------24 main------17 Thread-1------25 main------18 main------19 main------20 main------21 main------22 main------23 main------24 main------25 main------26 main------27 main------28 main------29 main------30 main------31 main------32 main------33 main------34 main------35 main------36 main------37 main------38 main------39 main------40 main------41 main------42 main------43 main------44 Thread-1------26 main------45 Thread-1------27 Thread-1------28 main------46 Thread-1------29 main------47 Thread-1------30 main------48 Thread-1------31 main------49 Thread-1------32 main------50 Thread-1------33 Thread-1------34 main------51 Thread-1------35 main------52 Thread-1------36 main------53 Thread-1------37 main------54 Thread-1------38 main------55 Thread-1------39 main------56 Thread-1------40 main------57 Thread-1------41 main------58 Thread-1------42 main------59 main------60 Thread-1------43 main------61 Thread-1------44 main------62 Thread-1------45 main------63 Thread-1------46 main------64 Thread-1------47 main------65 Thread-1------48 main------66 Thread-1------49 main------67 Thread-1------50 main------68 Thread-1------51 main------69 Thread-1------52 main------70 Thread-1------53 main------71 Thread-1------54 main------72 Thread-1------55 main------73 Thread-1------56 main------74 Thread-1------57 main------75 Thread-1------58 main------76 Thread-1------59 main------77 Thread-1------60 main------78 Thread-1------61 main------79 Thread-1------62 main------80 Thread-1------63 main------81 Thread-1------64 main------82 Thread-1------65 main------83 Thread-1------66 main------84 Thread-1------67 main------85 Thread-1------68 main------86 Thread-1------69 main------87 Thread-1------70 main------88 Thread-1------71 main------89 Thread-1------72 main------90 Thread-1------73 main------91 Thread-1------74 main------92 Thread-1------75 main------93 Thread-1------76 Thread-1------77 Thread-1------78 Thread-1------79 Thread-1------80 Thread-1------81 Thread-1------82 Thread-1------83 main------94 Thread-1------84 main------95 Thread-1------85 main------96 Thread-1------86 main------97 Thread-1------87 Thread-1------88 main------98 Thread-1------89 main------99 Thread-1------90 Thread-1------91 Thread-1------92 Thread-1------93 Thread-1------94 Thread-1------95 Thread-1------96 Thread-1------97 Thread-1------98 Thread-1------99
toString()

Thread类的toString方法返回该线程的字符串标识形式,包括线程名称、优先级和线程租Thread[Thread-0(线程名),5(优先级),main(所属线程组)]
优先级:
线程的优先级为1到10,每个相近的优先级之间其实没有太大差别,主要使用三个优先级 ,优先级高的线程在CPU执行权抢占的战斗中获胜的几率更大。




浙公网安备 33010602011771号