一、优雅的停止线程
开启线程的方式是:调用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无法描述同步的处理,他只是一种直接内存的处理,避免了副本的操作;