**多线程深入话题**
1:如何优雅的停止线程
在多线程之中如果要启动多线程肯定是Thread类中的start()方法,而如果对于多线程需要停止处理,Thread类原本提供有stop()方法,但是JDK1.2开始就将其废除了,而且一直到现在也不再建议出现在代码中,除了stop()之外还有几个方法被禁用了:
public class ThreadDemo {
public static boolean flag = true ;
public static void main(String[] args) throws Exception {
new Thread(() -> {
long num = 0;
while (flag) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在运行、num = " + num++);
}
}, "执行线程").start();
Thread.sleep(200); // 运行200毫秒
flag = false ; // 停止线程
}
}
2:守护线程
假设有一个人并且这个人有一个保镖,那么这个保镖一定是在这个人活着的时候进行守护,如果这个人死了,保镖没用了,所以在线程里面可以进行守护线程的定义,也就是说如果现在主线程或者其他线程还在执行的时候,那么守护线程将一直存在,并且运行在后台状态。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181111164322915.png
)
public class ThreadDemo {
public static boolean flag = true;
public static void main(String[] args) throws Exception {
Thread userThread = new Thread(() -> {
for (int x = 0 ; x < 10 ; x ++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在运行、x = " + x);
}
}, "用户线程"); // 完成核心的业务
Thread daemonThread = new Thread(() -> {
for (int x = 0 ; x < Integer.MAX_VALUE ; x ++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在运行、x = " + x);
}
}, "守护线程"); // 完成核心的业务
daemonThread.setDaemon(true); // 设置为守护线程
userThread.start();
daemonThread.start();
}
}
3;volatile关键字
在多线程的定义之中,volatile关键字只要是在属性定义上使用的,表示此属性为直接数据操作,而不进行副本的拷贝处理。
在正常进行标量处理的时候往往会经历如下几个步骤:
获取变量原有的数据内容副本;
利用副本为变量进行数学计算;
将计算后的变量,保存到原始空间中。
class Mythread implements Runnable{
private volatile int ticket = 5;//直接内存操作
@Override
public void run() {
synchronized (this) {
while(this.ticket>0) {
try {
Thread.sleep(100);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票处理,ticket"+this.ticket--);
}
}
}
}
public class Test{
public static void main(String args[]) {
Mythread mt= new Mythread();
new Thread (mt,"贩子A").start();
new Thread (mt,"贩子B").start();
new Thread (mt,"贩子C").start();
}
}
//运行结果
贩子A卖票处理,ticket5
贩子A卖票处理,ticket4
贩子A卖票处理,ticket3
贩子A卖票处理,ticket2
贩子A卖票处理,ticket1
多线程案例。