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