线程的状态及方法
线程的五个状态
线程的方法
1.线程的停止
测试停止线程
* 1.建议线程正常停止->根据次数,不建议死循环
* 2.建议使用标志位-设置一个标志位-flag
* 3.不要使用stop或destroy等过时或jdk不建议的方法
package thread; /* * 测试停止线程 * 1.建议线程正常停止->根据次数,不建议死循环 * 2.建议使用标志位-设置一个标志位-flag * 3.不要使用stop或destroy等过时或jdk不建议的方法 * */ public class TestStopThread implements Runnable{ private boolean flag = true; @Override public void run() { while (flag){ System.out.println("run........."); } } // 自定义停止线程的方法 public void stop(){ this.flag = false; } public static void main(String[] args) { TestStopThread testStopThread = new TestStopThread(); new Thread(testStopThread).start(); for (int i = 0; i < 1000; i++) { System.out.println("main"+i); if(i == 900){ // 调用自定义stop方法,来切换标志位,来停止线程 testStopThread.stop(); System.out.println("线程停止了!"); } } } }
2.线程的休眠(sleep())
1000ms=1s
sleep存在interruptedException异常,要抛出
sleep时间到后,线程会进入就绪状态
sleep可以模拟网络延迟、倒计时、输出当前系统时间等
每个对象都有一个锁,sleep不会释放对象锁
package thread; import java.text.SimpleDateFormat; import java.util.Date; public class TestSleepThread { public static void main(String[] args) throws InterruptedException { TestSleepThread test = new TestSleepThread(); test.tenDown(); // 打印当前系统时间 Date date = new Date(System.currentTimeMillis());//获取当前系统时间 while (true){ Thread.sleep(1000); System.out.println(new SimpleDateFormat("HH:mm:ss").format(date)); date = new Date(System.currentTimeMillis());//更新当前时间 } } // 模拟倒计时 public void tenDown() throws InterruptedException { int num = 10; while (true){ if (num <=0){ break; } Thread.sleep(1000); System.out.println(num--); } } }
3.线程的礼让(yield)
正在执行的线程停止,转为就绪状态,和就绪状态下的其他线程一起等待CPU的调度
礼让不一定成功,得看CPU的心情,有可能CPU又调用停止进入就绪状态下的进程。
package thread; public class TestYieldThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"开始执行"); Thread.yield();//礼让 System.out.println(Thread.currentThread().getName()+"执行结束"); } public static void main(String[] args) { TestYieldThread testYieldThread = new TestYieldThread(); new Thread(testYieldThread,"A").start(); new Thread(testYieldThread,"B").start(); } }
4.线程的强制执行(join()方法)
join合并线程,待此线程执行完成后,再执行其他线程,类似于插队。
package thread; //测试强制执行方法join,类似于插队 public class TestJoinThread implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("线程VIP来了"+i); } } public static void main(String[] args) throws InterruptedException { TestJoinThread testJoinThread = new TestJoinThread(); Thread thread = new Thread(testJoinThread); thread.start(); for (int i = 0; i < 500; i++) { if(i == 200){ thread.join(); } System.out.println("main线程运行"+i); } } }
5.线程状态查看(Thread.state)
1.创建线程thread
2.thread.getState(),查看线程状态
package thread; public class TestThreadstate { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("////////"); }); // 线程创建,查看线程状态 Thread.State state = thread.getState(); System.out.println(state);//NEW // 线程启动,进入就绪状态 thread.start();// state = thread.getState();//RUNABLE System.out.println(state); while (thread.getState() != Thread.State.TERMINATED){ Thread.sleep(1000); state = thread.getState(); System.out.println(state); } } }
6.线程的优先级
priority 优先级
线程的优先级低只意味被调度的概率低,并不是优先级低的就不会被调度,这得看CPU的调度
线程优先级的设置和查看用setPriority(),getPriority()两个方法
线程优先级的设置在start()方法之前
package thread; //线程的优先级 public class TestPriorityThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"的优先级为"+Thread.currentThread().getPriority()); } public static void main(String[] args) { TestPriorityThread testPriorityThread = new TestPriorityThread(); Thread t1 = new Thread(testPriorityThread); Thread t2 = new Thread(testPriorityThread); Thread t3 = new Thread(testPriorityThread); Thread t4 = new Thread(testPriorityThread); Thread t5 = new Thread(testPriorityThread); // 获取主线程的优先级 System.out.println("main的优先级为"+Thread.currentThread().getPriority()); t1.setPriority(1); t1.start(); t2.setPriority(2); t2.start(); t3.setPriority(5); t3.start(); t4.setPriority(7); t4.start(); t5.setPriority(10); t5.start(); } }
7.守护线程
daemon 守护
线程分为用户线程和守护线程
虚拟机必须保证用户线程执行完毕
虚拟机不用管守护线程是否执行完毕
守护线程的工作有记录后台操作日志、监控内存、垃圾回收等待等
package thread; public class TestDaemonThread { public static void main(String[] args) { GOD god = new GOD(); Person person = new Person(); Thread thread = new Thread(god); thread.setDaemon(true);//默认为false,为用户线程,正常的线程为用户线程,true则为守护线程 thread.start();//上帝 守护线程启动 虚拟机不会去管守护线程是否执行完毕,主要是用户线程的执行 new Thread(person).start();//人 用户线程启动 } } //上帝线程 class GOD implements Runnable{ @Override public void run() { while (true){ System.out.println("上帝一直保佑着你!"); } } } //你线程 class Person implements Runnable{ @Override public void run() { for (int i = 0; i < 36500; i++) { System.out.println("你开心的度过每一天"); } System.out.println("你安详的去世了!"); } }