常用方法:
long getId( ) - 用于返回当前线程的标识符/编号。
String getName( ) - 用于返回当前线程的名称。
void setName(String name) - 用于修改当前线程的名称。
static Thread currentThread( ) - 用于返回当前正在执行的线程对象的引用。
线程的主要状态
新建状态 -当线程对象刚被创建出来的状态;
-此时线程并没有开始执行;
就绪状态 -当线程调用start( )方法之后进入的状态;
-此时线程还是没有开始执行;
运行状态 -当线程调用调度器调度就绪状态的线程之后的状态;
-当时间片执行完毕但任务没有完成时 就回到就绪状态;
消亡状态 -当线程的任务已经完成时进入的状态;
阻塞状态 -当线程的执行过程中发生了阻塞事件(sleep)进入的状态。
-当阻塞状态解除之后进入就绪状态。
基本操作
static void yield( ) - 用于暂停当前正在执行的线程,转而执行其他线程。 - 让出CPU的执行权,回到就绪状态。
static void sleep(long millis) - 让当前正在执行的线程休眠参数指定的毫秒。
void interrupt( ) - 中断线程,通常用于打断睡眠。
void join( ) - 等待当前线程终止,没有时间的限制。
void join(long millis) - 最多等待当前线程参数指定的毫秒。
void setPriority(int newPriority) - 更改线程的优先级。
int getPriority( ) - 获取线程的优先级。 - 优先级最高的线程不一定最先执行,只是获取时间片的机会更多一些而已。
代码演示
案例1:获取线程的名称 和 编号
注意:修改线程的 名字,不能修改 编号
package com.monkey1026; public class Test extends Thread { // 继承了Thread线程类 public Test(String name) { // 有参构造 super(name); } @Override public void run() { System.out.println("子线程的编号是:"+getId()+",名称是: "+getName()); //其实这里是 this.getId() this.setName("二狗"); System.out.println("子线程的编号是:"+getId()+",名称是: "+getName()); } public static void main(String[] args) { //1.创建线程对象并启动 Thread t1=new Test("铁蛋"); t1.start(); System.out.println(); //获取当前线程对象的引用并且返回 Thread m = Thread.currentThread(); System.out.println("主线程的编号是:"+m.getId()+"主线程的名称是:"+m.getName()); } }
结果:
子线程的编号是:10,名称是: 铁蛋 主线程的编号是:1主线程的名称是:main 子线程的编号是:10,名称是: 二狗
案例2:测试线程休眠 (间隔时间)
需求: 模拟时钟的效果,每隔1秒钟,打印一次当前的系统时间;
进行5秒之后,停止时钟表工作。
package com.monkey1027; import java.text.SimpleDateFormat; import java.util.Date; public class ThreadSleepTest extends Thread { private boolean flag = true; public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } @Override public void run() { // 模拟时钟的效果,每隔一秒打印一次系统时间 while(flag) { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(date)); // 每间隔一秒打印一次 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
测试:
package com.monkey1027; public class Test { public static void main(String[] args) { // 创建线程 Thread thread = new ThreadSleepTest(); // 启动线程 thread.start(); System.out.println("主线程开始等待...."); // 希望 10 秒后,停止时钟 try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } // 使用stop()方法可以停止线程的执行 if(thread instanceof ThreadSleepTest) { ThreadSleepTest tts = (ThreadSleepTest)thread; tts.setFlag(false); // 改值为false,则while循环条件不成立。时钟停止 } } }
结果:
主线程开始等待.... 2019-11-05 09:30:19 2019-11-05 09:30:20 2019-11-05 09:30:21 2019-11-05 09:30:22 2019-11-05 09:30:23 2019-11-05 09:30:24 2019-11-05 09:30:25 2019-11-05 09:30:26 2019-11-05 09:30:27 2019-11-05 09:30:28
案例3:
.stop() 和 .interrupt()
模拟银行系统的取钞票过程
该代码 分析 控制台的结果
package com.monkey1028; public class ThreadInterrupt extends Thread { @Override public void run() { System.out.println("正在出钞,请稍后......."); // 模拟出钞的过程 try { // 让线程睡眠 10 秒钟 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("请取走您的钞票!"); } }
测试:
package com.monkey1028; public class Test { public static void main(String[] args) { Thread thread = new ThreadInterrupt(); thread.start(); // 开启线程 // 希望主线程等待 2 秒之后,就打断子线程的睡眠 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 打断子线程的睡眠之后,继续执行睡眠之后的语句 // thread.interrupt(); // 终止子线程的执行,睡眠之后的语句不会被执行了 thread.stop(); System.out.println("主线程结束了!"); } }
结果:
正在出钞,请稍后.......
主线程结束了!
案例4 . join( )方法 【重点】
package com.moneky1029; public class ThreadJoinTest extends Thread { @Override public void run() { for(int i=0;i<10;i++) { System.out.println("I am SuperMan! "+i); //打印10遍 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
测试:
package com.moneky1029; public class Test { public static void main(String[] args) { Thread t1=new ThreadJoinTest (); t1.start(); //主线程等待子线程的终止 try { //执行下面这行代码的是主线程,进入阻塞状态的是主线程。等待的是t1 //t1.join(); //主线程在等待子线程终止 t1.join(3000); //主线程等待3秒后,主线程执行。主线程执行完毕后,继续执行未执行完 的子线程 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("不抛弃不放弃,我们就叫钢七连"); } }
结果:
I am SuperMan! 0 I am SuperMan! 1 I am SuperMan! 2 不抛弃不放弃,我们就叫钢七连 I am SuperMan! 3 I am SuperMan! 4 I am SuperMan! 5 I am SuperMan! 6 I am SuperMan! 7 I am SuperMan! 8 I am SuperMan! 9
案例5: 线程优先级的设置
package com.monekey1030; public class ThreadPriorityTest extends Thread{ @Override public void run() { System.out.println("子线程的优先级是:"+getPriority()); for(int i=0;i<20;i++) { System.out.println("新线程中: i="+i); } } public static void main(String[] args) { Thread t1=new ThreadPriorityTest(); //为了使得子线程能更好的优先执行 t1.setPriority(MAX_PRIORITY); t1.start(); System.out.println("-------------------------------------"); System.out.println("主线程的优先级是 "+Thread.currentThread().getPriority()); for(int i=0;i<20;i++) { System.out.println("+++++++主线程中:i="+i); } } }
------------------------------------- 主线程的优先级是 5 子线程的优先级是:10 +++++++主线程中:i=0 新线程中: i=0 +++++++主线程中:i=1 新线程中: i=1 新线程中: i=2 新线程中: i=3 新线程中: i=4 新线程中: i=5 新线程中: i=6 新线程中: i=7 新线程中: i=8 新线程中: i=9 新线程中: i=10 新线程中: i=11 新线程中: i=12 新线程中: i=13 新线程中: i=14 新线程中: i=15 新线程中: i=16 新线程中: i=17 新线程中: i=18 新线程中: i=19 +++++++主线程中:i=2 +++++++主线程中:i=3 +++++++主线程中:i=4 +++++++主线程中:i=5 +++++++主线程中:i=6 +++++++主线程中:i=7 +++++++主线程中:i=8 +++++++主线程中:i=9 +++++++主线程中:i=10 +++++++主线程中:i=11 +++++++主线程中:i=12 +++++++主线程中:i=13 +++++++主线程中:i=14 +++++++主线程中:i=15 +++++++主线程中:i=16 +++++++主线程中:i=17 +++++++主线程中:i=18 +++++++主线程中:i=19