线程状态(二十二)
线程状态(二十二)
Daemon守护线程
在Java中我们默认开启的线程都是用户线程,而守护线程的作用就和他的名字一样,是守护着我们的用户线程运行;我们可以把用户线程和守护线程的关系理解成长跑运动员和陪跑员的关系。
我们先看一个例子:
package com.thread;
public class DaemonDemo {
public static void main(String[] args) {
God god = new God();
Thread thread = new Thread(god);
thread.setDaemon(true);
thread.start();
You you = new You();
new Thread(you).start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("God bless you...");
}
}
}
class You implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30000; i++) {
System.out.println("You have"+i+"happy days");
}
}
}
我们定义了两个线程God和You,God线程是一个死循环,但是在使用的时候,我把它设置成了守护线程,它会守护着you线程技术,在you线程运行结束后,god线程的守护使命就结束啦,也会相应的停下来,不会无止尽的循环下去。
Sleep线程休眠
Sleep线程休眠方法非常简单,就是在线程运行的过程中让线程停一会,可以模拟网络延迟情况下程序的运行。
package com.thread;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SleepDemo implements Runnable{
public static void main(String[] args) {
SleepDemo sd = new SleepDemo();
new Thread(sd).start();
}
@Override
public void run() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
while (true) {
Date date = new Date();
System.out.println(simpleDateFormat.format(date));
try {
//线程等待1000毫秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程停止
在Thread中提供了一些线程停止的方法,如stop()方法,但是Java官方不建议使用。所以我们常使用一个标识为来实现线程的停止。看代码:
package com.thread;
public class StopDemo implements Runnable{
private static boolean flag = true;
public static void main(String[] args) {
StopDemo sd = new StopDemo();
new Thread(sd).start();
stop();
}
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println("Threading output-->"+i);
i++;
}
}
public static void stop() {
for (int i = 0; i < 1000000000; i++) {
if (i==99999999) {
flag = false;
}
}
}
}
在上面的例子中,我们设置了一个flag标识位来作为线程停止的信号,当满足条件时更新flag的值,让线程的运行条件不满足,使得线程自己停下来;这样是停止线程比较安全的方式。
yield线程礼让
线程礼让,就是让一个运行中线程,从运行状态变为就绪状态;让CPU重新选择执行哪个线程。这里需要注意的是,是让CPU做选择,而不是主动让给另一个线程,所以最终执行哪个线程,有没有真的礼让,得看CPU的心情。
package com.thread;
public class YieldDemo implements Runnable{
public static void main(String[] args) {
YieldDemo yd = new YieldDemo();
Thread t1 = new Thread(yd, "A");
Thread t2 = new Thread(yd, "B");
t1.start();
t2.start();
}
@Override
public void run() {
for (int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
Thread.yield();
}
}
}
下面的结果是礼让成功的,当然也会有礼让不成功的情况。
A-->0
B-->0
A-->1
B-->1
join线程强制执行
join,通俗点说就是插队,在其他线程运行的时候,插队去运行,属于vip客户。
package com.thread;
public class JoinDemo implements Runnable{
public static void main(String[] args) throws InterruptedException {
JoinDemo jd = new JoinDemo();
Thread a = new Thread(jd, "A");
Thread b = new Thread(jd, "B");
a.start();
b.join();
b.start();
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
在运行结果中可以看到,A线程开始运行,然后B线程强行插队,等B线程运行完之后,A再继续运行,最后结束。