优雅的停止线程
在多线程操作之中如果要启动一个线程肯定是使用的Thread类中的start()方法,在Thread类中有提供停止线程的方法stop();但是这个方法从JDK1.2版本就已经废除了,不建议使用了。 实现线程柔和的停止:标记一个flag来控制线程的结束
后台守护线程
在Thread类里面提供有如下的守护线程的操作方法:
- 设置为守护线程:public final void setDaemon(boolean on);
- 判断是否为守护线程:public final boolean isDaemon(); 范例:使用守护线程
package cn.cccc.demo;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 (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在运行:x = " + x); } },"用户线程"); //完成核心业务17 collapsed lines
Thread daemonThread = new Thread(()->{ for(int x= 0; x <Integer.MAX_VALUE; x ++){ try { Thread.sleep(100); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在运行:x = " + x); } },"守护线程"); daemonThread.setDaemon(true); userThread.start(); daemonThread.start(); }}可以发现守护线程都是围绕着用户线程的周围,如果程序执行完毕,守护线程也就消失了。程序中最大的线程就是GC线程。 程序执行中GC线程会一直存在,如果程序执行完毕,GC线程也将消失。
volatile 关键字 在多线程定义之中, volatile关键字主要是在属性定义上使用的, 表示此属性为直接数据操作,而不进行副本的拷贝处理。这样的话在一些书上就将其错误的理解为同步属性了。 在正常进行变量处理的时候往往会经历如下的几个步骤:
- 获取变量原有的数据内容副本;
- 为变量进行数学计算;
- 将计算后的变量,保存到原始空间之中; 而如果一个属性上追加了volatile关键字,表示的就是不使用副本,而是直接操作原始数据,相当于节约了拷贝副本,重新保存的步骤。
package cn.cccc.demo;class MyThread implements Runnable{ private volatile int ticket = 5; //直接操作内存数据,节省了拷贝和重新赋值的时间,volatile的使用离不开Thread @Override public void run() { // TODO Auto-generated method stub synchronized (this) { while(this.ticket > 0 ){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在卖票,ticket = "+ this.ticket -- );14 collapsed lines
} }
}}public class ThreadDemo { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); new Thread(mt , "票贩子A").start(); new Thread(mt , "票贩子B").start(); new Thread(mt , "票贩子C").start(); }}