线程的五大状态
线程方法
线程停止
线程休眠
线程礼让
线程强制执行
观测线程状态
线程优先级
守护线程
点击链接跳转其他部分
多线程详解链接
线程状态
五大状态:
线程方法:
停止线程
不推荐使用JDK提供的stop(),destroy方法。已废弃@Deprecated
推荐线程自己停下来,利用次数,不建议死循环
建议使用一个标志位进行终止变量当flag=false,则终止线程运行。
public class TestStop implements Runnable {
//设置一个标识位
private boolean flag=true;
@Override
public void run() {
int i=0;
while (flag){
System.out.println("线程"+i++);
}
}
//设置一个公开的方法停止线程,转换标识位
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
Thread thread = new Thread(testStop);
thread.start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if (i==900){
testStop.stop();
System.out.println("该线程停止");
}
}
}
}
线程休眠
sleep指定当前线程阻塞的毫秒数;
sleep存在异常interruptedException;
sleep时间达到后线程进入就绪状态;
sleep可以模拟网络延时,倒计时等;
每一个对象都有一个锁,sleep不会释放锁;
import java.text.SimpleDateFormat;
import java.util.Date;
//模拟倒计时
public class TestStop2 {
public static void main(String[] args) {
TenDown();//倒计时
times();//自动更新当前时间
}
public static void TenDown(){
int num=10;
while (true){
if (num<=0) {
break;
}
try {
Thread.sleep(1000);
System.out.println(num--);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void times(){
Date starttime=new Date(System.currentTimeMillis());//获取当前时间
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(starttime));
starttime=new Date(System.currentTimeMillis());//更新当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程礼让-yield
礼让线程,让当前执行的线程暂停,但不阻塞
将线程才能够运行状态转为就绪状态
随机可能事件,但还是写一个
//测试礼让线程,礼让成功回到就绪状态,但还是要cpu分配,所以不一定成功
public class TestYield 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) {
TestYield testYield = new TestYield();
new Thread(testYield,"A").start();
new Thread(testYield,"B").start();
}
}
两种结果
join插队
join合并线程,待池线程执行完成后,在执行其他线程,其他线程阻塞
public class TestJoin 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 {
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主线程
for (int i = 0; i <= 100; i++) {
if (i==50) {
thread.join();//在50的时候被插队了
}
System.out.println("main"+i);
}
}
}
线程状态观测
多线程高并发考点:建议使用jdk帮助文档(api)Google版,以下是摘录:
Thread.State
线程可以处于以下状态之一
NEW
尚未启动的线程处于此状态。
RUNNABLE
在Java虚拟机中执行的线程处于此状态。
BLOCKED
被阻塞等待监视器锁定的线程处于此状态。
WAITING
正在等待另一个线程执行特定动作的线程处于此状态。
TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
TERMINATED
已退出的线程处于此状态
//观测线程的状态
public class TestState {
public static void main(String[] args) {
Thread thread=new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---------------");
}
});
//观察状态
Thread.State state=thread.getState();
System.out.println(state);
//观测启动后
thread.start();
state=thread.getState();
System.out.println(state);
while (state!=Thread.State.TERMINATED){
try {
Thread.sleep(100);
state=thread.getState();//更新线程状态
System.out.println(state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程的优先级
也是不一定成功
java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度那个线程来执行
优先级用数字标识,1~10,10最大
Thread.MAX_PRIORITY=10;
Thread.MIN_PRIORITY=1;
Thread.NORM_PRIORITY=5;
改变和获取优先级
Thread.currentThread().getPriority()
.setPriority();
public class TestPriority implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
TestPriority testPriority = new TestPriority();
Thread t1 = new Thread(testPriority);
Thread t2 = new Thread(testPriority);
Thread t3 = new Thread(testPriority);
Thread t4 = new Thread(testPriority);
Thread t5 = new Thread(testPriority);
//先设置优先级,再启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(4);
t3.start();
t4.setPriority(10);
t4.start();
t5.setPriority(10);
t5.start();
}
}
守护(daemon)线程
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待守护线程执行完毕
如,后台记录操作日志,监控内存,垃圾回收
public class TestDaemon {
public static void main(String[] args) {
Daemons daemons = new Daemons();
God god = new God();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false,用户线程;
thread.start();//守护线程走
new Thread(daemons).start();//用户线程启动
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("耶稣与你同在");
}
}
}
//你
class Daemons implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你已经活了"+i+"天");
}
System.out.println("再见,人间");
}
}