线程状态
线程方法
setPriority(int newPriority) 更改线程的优先级
static void sleep(long millis) 在指定的毫秒数内,让当前的执行的线程休眠
void join() 同步,使得线程之间的并行执行变为串行执行,a线程调用b线程的join方法,b线程执行完毕,a才会继续执行
static void yield() 展厅当前正在执行的线程对象,并执行其他线程
void interrupt() 中断线程,别用这个方式
boolean isAlive() 测试线程是否处于活动状态
线程停止
1. 建议线程正常停止--> 利用次数,不建议死循环
2. 建议使用标志位 --> 设置一个标志
3. 不要使用stop或者destroy等过时的JDK不建议使用的方法
- 设置一个标志位
- 设置一个公开的方法停止线程,转换标志位
package com.state;
/*
1. 建议线程正常停止--> 利用次数,不建议死循环
2. 建议使用标志位 --> 设置一个标志
3. 不要使用stop或者destroy等过时的JDK不建议使用的方法
*/
public class TestStop implements Runnable{
//1. 设置一个标志位
private boolean flag = true;
@Override
public void run () {
int i = 0;
while (flag){
System.out.println ("run...Thread"+i++);
}
}
//2. 设置一个公开的方法停止线程,转换标志位
public void stop(){
this.flag = false;
}
public static void main (String[] args) {
TestStop testStop = new TestStop ();
new Thread (testStop).start ();
for (int i = 0; i < 1000; i++) {
System.out.println ("main"+i);
if (i==900){
//调用stop方法,切换标志位,让线程停止
testStop.stop ();
System.out.println ("线程该停止了");
}
}
}
}
线程休眠
1s=1000ms
- sleep(时间)指定当前线程阻塞的毫秒数;
- sleep存在异常InterruptedException;
- sleep时间达到后线程进入就绪状态;
- sleep可以模拟网络延时,倒计时等。
- 每一个对象都有一个锁,sleep不会释放锁;
模拟网络延时:放大问题的发生性
package com.state;
//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable{
//票数
private int tickeNums = 10;
@Override
public void run () {
while (true){
if (tickeNums<=0){
break;
}
//模拟延时
try {
Thread.sleep (200);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println (Thread.currentThread ().getName ()+"-->拿到了第 "+tickeNums--+" 张票");
}
}
public static void main (String[] args) {
TestSleep ticket = new TestSleep ();
new Thread (ticket,"小明").start ();
new Thread (ticket,"老师").start ();
new Thread (ticket,"黄牛党").start ();
}
}
模拟倒计时
package com.state;
import java.text.SimpleDateFormat;
import java.util.Date;
//模拟倒计时
public class TestSleep2 {
public static void main (String[] args) {
//倒计时10s
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace ();
}
}
public static void tenDown () throws InterruptedException {
int num = 10;
while (true){
Thread.sleep (1000);
System.out.println (num--);
if (num<=0){
break;
}
}
}
}
每隔一秒打印当前时间
获取系统当前时间:Date startTime = new Date (System.currentTimeMillis ());
package com.state;
import java.text.SimpleDateFormat;
import java.util.Date;
//模拟倒计时
public class TestSleep2 {
public static void main (String[] args) {
//打印当前时间
Date startTime = new Date (System.currentTimeMillis ());//获取系统当前时间
while (true){
try {
startTime = new Date (System.currentTimeMillis ());//更新当前时间
System.out.println (new SimpleDateFormat ("HH:mm:ss").format (startTime));
Thread.sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
}
}
}
线程礼让
- 礼让线程,让当前正在执行的线程暂停,但不阻塞
- 将线程从运行状态转为就绪状态
- 让cpu重新调度,礼让不一定成功!看cpu心情
package com.state;
/*
测试礼让线程
礼让不一定成功
*/
public class TestYield {
public static void main (String[] args) {
MyYield myYield = new MyYield ();
NoYield noYield = new NoYield ();
new Thread (myYield,"a").start ();
new Thread (noYield,"b").start ();
}
}
class MyYield implements Runnable{
@Override
public void run () {
System.out.println (Thread.currentThread ().getName ()+"线程开始执行");
Thread.yield ();//礼让
System.out.println (Thread.currentThread ().getName ()+"线程停止执行");
}
}
class NoYield implements Runnable{
@Override
public void run () {
System.out.println (Thread.currentThread ().getName ()+"线程开始执行");
System.out.println (Thread.currentThread ().getName ()+"线程停止执行");
}
}
join
- Join 合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞
- a线程调用b线程的join方法,b线程执行完毕,a才会继续执行
package com.state;
/*
测试join方法:可以想象为插队
*/
public class TestJoin implements Runnable{
@Override
public void run () {
for (int i = 0; i < 1000; i++) {
System.out.println ("线程vip来了"+i);
}
}
public static void main (String[] args) throws InterruptedException {
//启动线程
TestJoin testJoin = new TestJoin ();
Thread thread = new Thread (testJoin);
thread.start ();
//主线程
for (int i = 0; i < 500; i++) {
if (i==200){
thread.join ();//插队
}
System.out.println ("main"+i);
}
}
}
结果:a,main并发执行,执行到main199之后main暂停执行,等待a执行完毕,再执行main200-499; 假如将start放在if里面,那么结果就是:main单独执行到199之后,由a执行,到a执行完,再由main执行
线程状态观测
获取线程的状态:thread.getState ();
Thread.State 线程状态:
- NEW
- 尚未启动的线程
- RUNNABLE
- 在java 虚拟机中执行的线程处于此状态
- BLOCKED
- 被阻塞等待监视器锁定的线程出于此状态
- WATING
- 正在等待另一个线程执行特定动作的线程处于此状态
- TIMED_WAITING
- 正在等待另一个线程执行动作达到指定时间的线程处于此状态
- TERMINATED
- 已退出的线程处于此状态
线程中断或者结束之后,就不能再次启动了
- 已退出的线程处于此状态
package com.state;
/*
观测线程状态
*/
public class TestState {
public static void main (String[] args) throws InterruptedException {
Thread thread = new Thread (()->{
try {
Thread.sleep (5000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println ("---------");
});
//观察状态
Thread.State state = thread.getState ();
System.out.println (state);//NEW
//观察启动后
thread.start ();//启动线程
System.out.println (thread.getState ());//RUN
while (state != Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
state = thread.getState ();//更新线程状态
System.out.println (state);//输出状态
Thread.sleep (100);
}
}
}