一、优雅的停止线程
开启线程的方式是:调用Thread中的start()方法,停止线程的方式:原本Thread提供了stop()方法,但是在JDK1.2坂本后就已经被禁用了。除了stop(),还有几个方法被禁用
例如:
1.停止多线程:public void stop();
2.销毁多线程:public void destory();
3.挂起线程:public final void suspend();
4.恢复挂起的线程执行public final void resume();
这些方法被禁用的原因是因为:可能会导致死锁。
范例:实现线程优雅的停止
public class ThreadDemo3 {
public static boolean flag = true;
public static void main(String[] args) throws Exception{
new Thread(()->{
long m = 0;
while (flag){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" The number is "+m++);
}
},"执行线程").start();
Thread.sleep(200);
flag=false;
}
}
二、后台守护线程
充当保镖的角色,在多线程里面可以进行守护线程的定义,也就是说如果现在主线程的程序或其他线程在执行的时候,守护线程将一直存在。
1.设置为守护线程:public final void setDaemon(boolean on);
2.是否为守护线程:public final boolean isDaem();
范例:守护线程的使用
public class ThreadDemo4 {
public static void main(String[] args) throws Exception {
Thread userThread = new Thread(()->{
for(int i = 0; i< 10; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"num = "+i);
}
},"用户线程");
Thread daemonThread = new Thread(()->{
for(int i = 0; i< Integer.MAX_VALUE; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"num = "+i);
}
},"守护线程");
daemonThread.setDaemon(true);
userThread.start();
daemonThread.start();
}
}
运行结果:
可以发现所有的守护线程都是围绕在用户线程的周围,如果程序执行完毕,守护线程也就没有存在的必要了,最大的守护线程就是GC线程。
三、volatile关键字
在多线程的定义中,volatile关键字主要是在属性定义上使用的,表示此属性为直接数据操作,而不进行副本的拷贝处理。
在我们正常进行变量处理的时候往往会经历如下几个步骤:
1.获取变量原有的数据内容副本;
2.利用副本为变量进行数学计算;
3.将计算后的变量,保存到原始空间之中;
而如果一个属性追加了volatile关键字,表示的就是不使用副本,而是直接操作原始变量。
范例:valatile的正确使用
class MyThread implements Runnable{
public 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 = " + ticket--);
}
}
}
}
public class Main {
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();
}
}
面试题:请解释volatile与synchronized的区别?
1.volatile主要是属性上使用,而synchronized是在代码块和方法上使用的;
2.volatile无法描述同步的处理,他只是一种直接内存的处理,避免了副本的操作;