美文网首页
面试常问,一半以上的人容易忽略的,线程同步问题

面试常问,一半以上的人容易忽略的,线程同步问题

作者: alcohol和cat | 来源:发表于2019-07-31 19:31 被阅读0次

    什么是线程同步?

    当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题。

    为什么要线程同步?

    因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常

    同步机制:

    在多线程中,可能有多个线程试图访问一个有限的资源,必须预防这种情况的发生。所以引入了同步机制:在线程使用一个资源时为其加锁,这样其他的线程便不能访问那个资源了,直到解锁后才可以访问。

    Java多线程支持方法同步,方法同步只需用用synchronized来修饰方法即可,那么这个方法就是同步方法了。

    五种同步线程的方法

    1.同步方法:使用sychronized关键字修饰方法,由于java的每个对象都有一个内置锁,当用此关键字修饰方法(静态与非静态都可修饰)时,内置锁会保护整个方法,在调用该方法时,在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

    2.同步代码块:既有sychronized修饰的语句块,被该关键字修饰的语句块会被自动加上内置锁,从而实现同步。(注意:线程同步是一个高开销的操作,因此应当尽量减少同步的内容,通常没必要同步整个方法)

    /*** 定义一个类,包含了线程类需要调用的方法 */class Compute1{//通过同步代码块锁定object1对象进行锁定了其他同样的synchronized代码块

    privateObjectobject1 =newObject();

    publicvoidexecute(){synchronized(object1)

    {

    for(inti =0; i<100; i++){try{ Thread.sleep(100);

     }

    catch(InterruptedException e) { e.printStackTrace(); 

    }

     System.out.println("compute1:execute1 "+ i++);

     } }  }

    publicsynchronizedvoidexecute2()

    {synchronized(object1)

    {

    for(inti =0; i<100; i++){try{ Thread.sleep(100);

     }

    catch(InterruptedException e) { e.printStackTrace();

     }

     System.out.println("compute1:execute2 "+ i++);

     } } }}

    如果想要使用synchronized同步代码块达到和使用synchronized方法同样的效果,可以锁定this引用:

    synchronized(this){…}

    3.使用特殊域变量(Volatile)实现线程同步.因为Volatile不能保证原子操作导致的,因此Volatile不能代替sychronized,此外Volatile会组织编译器对代码优化,因此不建议使用它,

    4.使用重入锁对线同步(javaSE5.0以上中新增了一个java.util.concurrent包来支持同步)

    5.使用局部变量实现线程同步

    原文来自公众号"源码星球"

    相关文章

      网友评论

          本文标题:面试常问,一半以上的人容易忽略的,线程同步问题

          本文链接:https://www.haomeiwen.com/subject/xwgtdctx.html