三种方式停止当前线程
设置标志位(无法处理线程阻塞时的问题)
class TStop implements Runnable {
//设置标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println(Thread.currentThread().getName() + "执行 i = " + (i++));
}
}
//转换标志位
public void setFlag() {
this.flag = false;
}
}
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
TStop tp = new TStop();
Thread thread = new Thread(tp,"线程A");
thread.start();
for (int i = 0; i < 1000; i++) {
System.out.println("[main]->" + i);
if (i == 900) {
//thread.stop();不建议使用stop方法强制停止线程
tp.setFlag();
Thread.sleep(100);
System.err.println("线程A执结束!");
}
}
}
}
为什么说stop方法强行关闭线程不安全呢?
因为stop会解除由线程获取的所有锁,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止。
假如一个线程正在执行:
synchronized void { x = 3; y = 4;}
由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到 x=3
时,被调用了stop方法,当前线程会被强制停止执行,导致y
没有被赋值。即使在同步块中,它也会立即stop,这样就产生了不完整的残缺数据。
若线程中没有使用类似sleep/wait/join
时(使线程进入阻塞态),调用此线程对象的interrupt
不会真正中断线程,只是简单的将线程的状态置为interrupt而已,根据此状态来进一步确定如何处理线程
class ThreadRupt implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println("收到中断信号!");
e.printStackTrace();
break;
}
}
}
}
public class ThreadInterrupt {
public static void main(String[] args) throws InterruptedException {
ThreadRupt tr = new ThreadRupt();
Thread thread = new Thread(tr);
Thread.sleep(1000);
thread.start();
System.out.println("是否中断?"+ thread.isInterrupted());
thread.interrupt();
System.out.println("是否中断?"+ thread.isInterrupted());
}
}
Thread类提供的isInterrupted
方法,测试这个线程是否被中断
若线程中调用了阻塞线程的方法sleep/wait/join
方法,此时再掉用线程的 interrupt
方法会抛出异常,同时线程状态还原 isInterrupted = false
class MyThreadStop implements Runnable {
private boolean flag = true;
@Override
public void run() {
int i = 0;
while(flag) {
try {
Thread.sleep(1000);
boolean bool = Thread.currentThread().isInterrupted();
if(bool) {
System.out.println("非阻塞情况!线程的中断状态: " + bool);
break;
}
System.out.println("第" +i+ "次执行,线程名称为:" + Thread.currentThread().getName() + "执行 i = " + (i++));
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程中断……");
System.out.println(Thread.currentThread().isInterrupted());
//退出循环
break;
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
MyThreadStop threadStop = new MyThreadStop();
Thread thread = new Thread(threadStop,"子线程A ");
thread.start();
Thread.sleep(5000);
thread.interrupt();
System.out.println("Main 方法执结束!");
}
}
interrupt()源码:
线程的优先级指的是优先级越高 越有可能被先执行
就拿买彩票来说,买100张彩票的中奖几率一定是大于一张的,但是买100张彩票就一定会中奖吗?搏一搏,单车变摩托?
同样的道理,线程的优先级越高,越有可能被先执行。执行的机率加大,但具体是否执行,还得看CPU的调度
设置线程优先级 setPriority(int priority)
获取优先级 int getPriority
JDK内置的三种优先级:
MAX_PRIORITYT = 10
NORM_PRIORITYT = 5
MIN_PRIORITYT = 1
main线程默认的优先级为 NORM_PRIORITYT = 5
优先级的设定: 优先级的设定要放到启动线程之前
线程的继承性: 在一个线程中创建了子线程,默认子线程与父线程的优先级相同
public class ThreadPriority 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());
ThreadPriority tp = new ThreadPriority();
Thread t1 = new Thread(tp);
Thread t2 = new Thread(tp);
Thread t3 = new Thread(tp);
Thread t4 = new Thread(tp);
Thread t5 = new Thread(tp);
t1.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.setPriority(3);
t2.start();
t3.setPriority(Thread.NORM_PRIORITY);
t3.start();
t4.setPriority(7);
t4.start();
t5.setPriority(Thread.MAX_PRIORITY);
t5.start();
}
}
Java中线程分为:
守护线程为陪伴线程,只要JVM中存在任何一个用户线程没有终止,守护线程就一直在工作。JVM必须确保用户线程执行完毕,但是不用等待守护线程
默认创建的线程都是用户线程,包括主线程
通过setDaemon(true)
将线程对象设置为守护线程
典型的守护线程:垃圾回收线程、内存监控、日志记录
class God implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("God Bless you!");
}
}
}
class Person implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Live happily...");
}
System.err.println("--> 撒由那拉!!!");
}
}
public class ThreadDaemon {
public static void main(String[] args) throws InterruptedException {
God god = new God();
Person per = new Person();
Thread thread = new Thread(god);
//设置上帝为守护线程
thread.setDaemon(true);
thread.start();
new Thread(per).start();
}
}