zoukankan      html  css  js  c++  java
  • 多线程(二)

    (一)如何正确的停止一个线程?

    停止一个线程意味着在任务处理完之前停止,也就是放弃当前的操作。停止一个线程可以yogaThread.stop()方法,但是最好不要用它,因为该方法是不安全的,而且该方法已经被废弃。

    在java中有三种停止线程的方法:

      1、是线程正常退出,也就是当run()方法完成后种植线程

      2、使用stop()方法强行终止,但是不推荐使用该方法,该方法与suspend,resume医用已经被废弃

      3、使用interrupt方法终端线程,Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。 

               因此,如果线程被上述几种方法阻塞,正确的停止线程方式是设置共享变量,并调用interrupt()(注意变量应该先设置)。如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。在任何一种情况中,最后线程都将检查共享变量然后再停止这个示例描述了该技术。 

     1 class Example3 extends Thread {
     2   volatile boolean stop = false;
     3   public static void main( String args[] ) throws Exception {
     4    Example3 thread = new Example3();
     5    System.out.println( "Starting thread..." );
     6    thread.start();
     7    Thread.sleep( 3000 );
     8    System.out.println( "Asking thread to stop..." );
     9    thread.stop = true;//如果线程阻塞,将不会检查此变量
    10    thread.interrupt();
    11    Thread.sleep( 3000 );
    12    System.out.println( "Stopping application..." );
    13    //System.exit( 0 );
    14   }
    15 
    16   public void run() {
    17     while ( !stop ) {
    18      System.out.println( "Thread running..." );
    19       try {
    20       Thread.sleep( 1000 );
    21       } catch ( InterruptedException e ) {
    22       System.out.println( "Thread interrupted..." );
    23       }
    24     }
    25    System.out.println( "Thread exiting under request..." );
    26   }
    27 }

    一旦Thread.interrupt()被调用,线程便收到一个异常,于是逃离了阻塞状态并确定应该停止。运行以上代码将得到下面的输出: 

    Starting thread... 
    Thread running... 
    Thread running... 
    Thread running... 
    Asking thread to stop... 
    Thread interrupted... 
    Thread exiting under request... 
    Stopping application...

    (二)线程安全

    线程安全就是多线程访问同一代码,不会产生不确定的结果。

    如何保证线程安全? 

    (1)最简单的方式是加入synchronized关键字,这会获取对象锁,其他线程函数将被一直阻塞

    (2)使用锁

    区别:

    a.Lock使用起来比较灵活,但需要手动释放和开启;

    b.Lock只适用于与代码块锁,而synchronized对象之间是互斥!

     (三)synchronized如何使用

    synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
    1). 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
    2). 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
    3). 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
    4). 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

    (四)synchronized和Lock的区别

    http://www.cnblogs.com/baizhanshi/p/6419268.html

    总结来说,Lock和synchronized有以下几点不同:

      1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

      2)synchronized发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally中释放锁;

      3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

      4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

      5)Lock可以提高多个线程进行读操作的效率。

      在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

    主要相同点:Lock能完成synchronized所实现的所有功能
    主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。Lock的锁定是通过代码实现的,而synchronized是在JVM层面上实现的,synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。Lock锁的范围有局限性,块范围,而synchronized可以锁住块、对象、类,wait、notifyf必须在synchronized中执行。

           1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;

      2)Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。

    ReentrantLock(可重入锁)是唯一实现了Lock接口的类。

    (五)sleep和wait的区别(考察是否会释放锁)

    sleep()方法是Thread类中方法,而wait()方法是Object类中的方法。
    sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态,在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备。

    面试题:http://www.cnblogs.com/dolphin0520/p/3932934.html

  • 相关阅读:
    normalize.css 中文版
    [转载]自适应高度输入框
    【转载】H5页面列表的无线滚动加载(前端分页)
    CSS设置table下tbody滚动条与thead对齐的方法
    [转载]Jquery mobiscroll 移动设备(手机)wap日期时间选择插件以及滑动、滚动插件
    wordpress 目录、数据结构和解析原理
    WordPress基础知识:条件判断标签及用法大全
    主题如何添加tag标签页面
    WordPress进阶:[2]不同页面显示不同的侧边栏
    WordPress进阶:[1]怎样用tag标签做导航菜单
  • 原文地址:https://www.cnblogs.com/wangleBlogs/p/7365677.html
Copyright © 2011-2022 走看看