ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

多线程 2

多线程 2 1. Thread 类、常见方法1.1 常用构造方法方法说明Thread()创建线程对象Thread( Runnable target)使用 Runnable 对象创建线程对象Thread(String name)创建线程对象并命名Thread( Runnable target String name)使用 Runnable 对象创建线程对象并命名1.2 线程的常见属性属性获取方法IDgetId()名称getNname()状态getState()优先级getPriority()是否是后台线程isDaemon()是否存活isAlive()是否中断isInterrupted()获取线程的名称Threadt1newThread();//给线程起名字Threadt2newThread(线程2);Threadt3newThread(newRunnable(){Overridepublicvoidrun(){}},线程3);//getName 获取线程的名字System.out.println(t1.getName());System.out.println(t2.getName());System.out.println(t3.getName());线程的名字默认是Thread - 数字, 给线程起名字可以在线程数量很多的情况下更方便地观察线程1.3 前台线程和后台线程前台线程 会阻止进程的结束后台线程 不会阻止进程的结束publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtnewThread(()-{for(inti0;i5;i){System.out.println(thread);try{// 睡眠 1 秒Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}System.out.println(t线程结束);});t.start();// 睡眠 1 秒Thread.sleep(1000);System.out.println(主线程结束);// main 和 t 都是前台线程 2 个线程都结束 进程才结束}进程默认就是前台线程可以通过setDaemon(true)把线程设置为 后台线程参数是 true 表示是后台线程, 默认是 false 表示前台线程要在线程开启前设置publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtnewThread(()-{for(inti0;i5;i){System.out.println(thread);try{// 睡眠 1 秒Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}System.out.println( t 线程结束);});// 在 strat() 开始前 把 t 设置成 后台线程(守护线程)t.setDaemon(true);t.start();// 睡眠 1 秒Thread.sleep(1000);System.out.println(主线程结束);// 前台线程结束了 进程就结束}1.4 start( )strart()会调用操作系统的 API , 在操作系统中创造出一个线程Java为了让一个 thread 对象和 一个操作系统线程 一一对应, 每个线程只能调用一次start()publicstaticvoidmain(String[]args){Threadt1newThread(()-{System.out.println(t1 thread);});t1.start();t1.start();}1.5 中断线程中断线程的 2 种方式 通过共享标记进行沟通通过调用 interrupt( ) 方法使用自定义变量作为标识位privatestaticbooleanrunningtrue;publicstaticvoidmain(String[]args){ThreadtnewThread(()-{while(running){System.out.println(thread t);try{Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}});t.start();try{//睡眠 4 秒后 中断线程Thread.sleep(4000);runningfalse;}catch(InterruptedExceptione){thrownewRuntimeException(e);}}使用 interrupt( )publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtnewThread(()-{// currentThread 获取 t 线程的引用ThreadcurThread.currentThread();//isInterrupted 判断 t 线程的标识位while(!cur.isInterrupted()){System.out.println(thread);try{//预计 sleep 100 秒Thread.sleep(100_000);}catch(InterruptedExceptione){e.printStackTrace();}}});t.start();Thread.sleep(1000);// 设置 t 线程的标识位t.interrupt();}interrupt()能设置标志位还能唤醒 sleep 等导致线程堵塞的方法Q :为什么这里会在线程中止后又打印 thread ?A :interrupt()设置标识位为true唤醒sleep()让sleep()抛出异常后sleep()自动重新设置标识位为falseThread.currentThread(): 获取当前线程的引用publicstaticvoidmain(String[]args){//获取主线程的引用ThreadmainThreadThread.currentThread();System.out.println(mainThread.getName());}如果在主线程执行Thread.currentThread()就是获取主线程的引用在thread1线程中执行Thread.currentThread()就是获取thread1线程的引用1.6 join( ) 线程等待privatestaticintsum0;publicstaticvoidmain(String[]args){ThreadtnewThread(()-{for(inti1;i1000;i){sumi;}});t.start();System.out.println(sum sum);}要求是 等t 线程计算完1~1000的和之后 主线程再进行打印和结果是t线程还没有计算 主线程就打印结果了如果使用sleep()让 主线程睡一会睡少了t 线程还没有计算完睡多了又浪费时间另外如果t 线程的逻辑复杂,sleep()就更不适用这时使用join()就能让一个线程执行结束后再继续执行方法说明join()当前线程一直等待直到目标线程执行完毕才继续join( long millis )当前线程最多等待 millis 毫秒超时后无论目标线程是否结束当前线程都会继续执行privatestaticintsum0;publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtnewThread(()-{for(inti1;i1000;i){sumi;}});t.start();t.join();System.out.println(sum sum);}join()如果目标线程一直不结束那就会一直等下去publicstaticvoidmain(String[]args)throwsInterruptedException{//获取 main 线程的引用ThreadmainThread.currentThread();System.out.println(开始等待);main.join();System.out.println(线程结束);}join( long millis )等待设置的 ms 后继续执行publicstaticvoidmain(String[]args)throwsInterruptedException{//获取 main 线程的引用ThreadmainThread.currentThread();System.out.println(开始等待);//等待 2 秒main.join(2000);System.out.println(线程结束);}如果调用join前线程就已经执行完了再次调用join是线程不会堵塞2. 线程的状态线程的 6 种状态状态表示NEW创建了 Thread 对象但没有 start()TERMINATED操作系统线程销毁(线程的执行入口执行完了)但 thread 对象还在RUNNABLE可运行的 1.CPU 正在执行 2.等待CPU调度执行就绪WAITING线程无限等待 调用无参 join()目标线程不结束等待进程的状态TIMED_WAITING线程有限等待 调用join(long millis) 过程中等待进程的状态BLOCKED由于锁导致的堵塞NEW 、RUNNABLE 、TERMINATED 状态的转换publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtnewThread(()-{});System.out.println(t.getState());t.start();System.out.println(t.getState());t.join();System.out.println(t.getState());}WAITINGpublicstaticvoidmain(String[]args)throwsInterruptedException{ThreadmainThreadThread.currentThread();ThreadtnewThread(()-{while(true){System.out.println(mainThread state mainThread.getState());}});t.start();t.join();}TIMED_WAITINGpublicstaticvoidmain(String[]args)throwsInterruptedException{ThreadmainThreadThread.currentThread();ThreadtnewThread(()-{while(true){System.out.println(mainThread state mainThread.getState());}});t.start();t.join(10000);}
返回列表