zoukankan      html  css  js  c++  java
  • 进阶Java编程(4)多线程深入话题

    多线程深入话题

    1,优雅的停止线程

      在多线程操作之中如果要启动多线程使用的肯定是Thread类中的start()方法,而如果对于多线程需要进行停止处理,Thread类原本提供有stop()方法,但是这些方法从JDK1.2版本就已经将其废弃【@Deprecated】了,而且一直到现在也不在建议出现在代码之中。

    停止多线程

    public void stop()

    销毁多线程

    public void destroy()

    挂起线程

    public final void suspend()暂停执行

    恢复挂起的线程执行

    public final void resume()

      之所以废除这些方法,主要的原因是因为这些方法有可能导致线程的死锁,所以从JDK1.2开始就都不建议使用了。如果现在要想实现线程的停止需要通过一些柔和的方式来进行。

      ·范例:实现线程柔和的停止

     1 public class Main {
     2 public static boolean flag=true;
     3 public static void main(String[] args) throws InterruptedException{
     4 new Thread(()->{
     5 long num=0;
     6 while (flag){
     7 try{
     8                     Thread.sleep(50);
     9                 }catch(InterruptedException e){
    10                     e.printStackTrace();
    11                 }
    12                 System.out.println(Thread.currentThread().getName()+"正在运行,num="+num++);
    13             }
    14         },"执行线程").start();
    15         Thread.sleep(200);
    16 flag=false;
    17     }
    18 }

      备注:现在这种方法是解决循环死锁最好用也是最方便的方法。  万一现在有其他线程去控制这个flag的内容,那么这个时候对于线程的停止也不是说停就立刻停止的,而是在运行中判断flag的内容来决定。

    2,后台守护线程

      现在假设有一个人并且这个人有一个保镖,那么这个保镖一定是在这个人活着的时候进行守护,如果这个人已经死了,保镖没有用了。所以在多线程里面可以进行守护线程的定义,也就是说如果主线程的程序或者其它的线程还在执行的时候,那么守护线程将一直存在,并且运行在后台的状态。

      在Thread类里面提供有如下的守护线程的操作方法:

      ·范例:使用守护线程

     1 public class Main {
     2 public static boolean flag=true;
     3 public static void main(String[] args) throws InterruptedException{
     4         Thread userThread = new Thread(()->{
     5 for(int x=0;x<10;x++){
     6 try {
     7                     Thread.sleep(100);
     8                 } catch (InterruptedException e) {
     9                     e.printStackTrace();
    10                 }
    11                 System.out.println(Thread.currentThread().getName()+"正在运行,x="+x);
    12             }
    13         },"用户线程");//完成核心的业务
    14 Thread daemonThread = new Thread(()->{
    15 for(int x=0;x<Integer.MAX_VALUE;x++){
    16 try {
    17                     Thread.sleep(100);
    18                 } catch (InterruptedException e) {
    19                     e.printStackTrace();
    20                 }
    21                 System.out.println(Thread.currentThread().getName()+"正在运行,x="+x);
    22             }
    23         },"守护线程");//完成核心的业务
    24 daemonThread.setDaemon(true);
    25         userThread.start();
    26         daemonThread.start();
    27     }
    28 }

    3,volatile关键字

      可以发现所有的守护线程都是在围绕用户线程的周围,如果程序执行完毕了,守护线程也就消失了,在整个JVM里面最大的守护线程就是GC线程!对啊,程序都完结了,那么该守护线程GC也就没有存在的意义了。

      在多线程的定义之中,volatile关键字主要是在属性定义上使用的,表示此属性为直接数据操作,而不是进行副本的拷贝处理,这样的话,在一些书上就错误的将其理解为同步属性。

      在正常进行变量处理的时候往往会经历如下的几个步骤:

        ①获取变量原有的变量内容副本;

        ②利用副本为变量进行数学计算;

        ③将计算后的变量,保存到原始空间之中;

      而一个属性上追加了volatile关键字,表示不使用副本,而是直接操作相当于节约:拷贝副本、重新保存的步骤。

      ·范例:volatile正确用法【与同步没有什么关系,只与更快的数据存取有关】

     1 class MyThread implements Runnable{
     2 private volatile int ticket=5;//直接内存操作
     3 @Override
     4 public void run() {
     5 synchronized(this){
     6 while (this.ticket>0){
     7 try {
     8                     Thread.sleep(100);
     9                 } catch (InterruptedException e) {
    10                     e.printStackTrace();
    11                 }
    12                 System.out.println(Thread.currentThread().getName()+"卖票处理,ticket="+this.ticket--);
    13             }
    14         }
    15     }
    16 }
    17 public class Main {
    18 public static void main(String[] args) throws InterruptedException{
    19         MyThread mt=new MyThread();
    20 new Thread(mt,"票贩子A").start();
    21 new Thread(mt,"票贩子B").start();
    22 new Thread(mt,"票贩子C").start();
    23     }
    24 }

      ①volatile主要在属性上使用,而synchronized是在代码块与方法上使用的;面试题:请解释volatile与synchronized的区别?

      ②volatile无法描述同步的处理,它只是一种直接的内存处理,避免了副本的操作,而synchronized是实现同步的。

  • 相关阅读:
    Poj(1703),种类并查集
    Poj(2236),简单并查集
    Poj (3239),m皇后问题
    Poj(1521),哈夫曼编码
    NYOJ(680),摘枇杷,(暴力,或者二分搜索)
    NYOJ(42)欧拉图
    数集合有多少个TOJ(2469)
    HDU(1016),打素数环
    HDU(4394),数论上的BFS
    Poj(2225),三维BFS
  • 原文地址:https://www.cnblogs.com/Mufasa/p/11140629.html
Copyright © 2011-2022 走看看