`

JAVA并发基础知识

    博客分类:
  • JAVA
· 
阅读更多

对象的状态 : 指存储在状态变量中的数据

 

同步机制:

synchronized,它提供了一种独占锁,但同步这个术语还包括volatile类型的变量,显式锁以及原子变量。

注意 : 如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出错,可以通过下面的三种方法来解决。

不在线程之间共享该状态变量、将状态变量修改为不可变的变量、在访问状态变量时使用同步。

 

 

一、线程安全性:当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类时线程安全的。线程安全类中封装了必要的同步机制,不须客户端采取同步措施

无状态的对象一定是线程安全的 

 

二、原子性:为了避免竞态条件,就必须在某个线程修改该变量时,通过某种方式防止其他线程使用整个变量 

  1:竞态条件 :由于不恰当的执行时序而出现不正确的结果,例如延迟初始化就会产生这样的情况。

      

       2:要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量 

 

三、加锁机制

 

        1:java内置锁(互斥锁) : java提供了一种内置的锁机制来支持原子性(同步代码块)

             同步代码块包括两部分,一个作为锁的对象引用、一个作为由这个锁保护的代码块

             以关键字synchronize来修饰的方法是一种横跨整个方法体的同步代码块,其中该同步代码块的锁就是方法调用所在的对象

             静态的synchronized方法以Class对象作为锁

 

       2:重入 : 同一个线程可以多次获得同一个锁。

              当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。重入的一种实现方法是,为每个锁关联一个获取计数值和一个所有者线程。

当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的锁时,jvm将记下锁的持有者,并且将获取计数值置为1。如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会相应地会相应地递减。当计数值为0时,这个锁将被释放。

 

如果没有使用重入:会发生死锁

 

           public class A {

                    public synchronized void doSomething(){

                   

                    }

           }

 

          public class B extends A {

                    public synchronized void doSomething(){

                           super.doSomething();

                    }

          }

 

 

 四、用锁来保护状态

        如果用同步来协调某个变量的访问,那么在访问这个变量的所有位置上有需要使用同步

        使用锁来对某个变量的访问时,在访问变量的所有位置上都要使用同一个锁

        对于可能被多个线程同时访问的可变状态变量,在访问它时都需要持有同一个锁

 

五、可见性 :没有使用足够的同步机制,无法保证一个线程写入的值,对于另一个线程读的值是可见的

 

volalite 变量 : 不会加锁,不会使线程阻塞,通过将变量的更新通知到其它线程,来实现同步。当只有确保单线程修改这个变量时,才可使用

 

 

六、线程封闭

1、java语言提供了一些机制来维持线程封闭:局部变量(栈封闭)和ThreadLocal类

 

七、不变性

1、不可变对象一定是线程安全的,不需要同步

2、final 修改的变量时引用不可修改,对象还是可以修改的

 

3、事实不可变 : 同不可变对象一样

public map<String,Date> lastLogin = Collections.synchronizeMap(new HashMap<String,Date>);

 

 

八、安全发布

1: 在静态初始化函数中初始化一个对象引用

2: 将对象的引用保存到volatile类型的域或者atomic对象中

3: 将对象的引用保存到某个正确构造对象的final类型域中

4: 将对象的引用保存到有锁保存的域 (线程安全容器就是通过这个的方式实现的) 

 

5:    线程安全库的容器类:下面都可以安全地将它发布给任何从这些容器中访问它的线程

将键或值,放到hashtable、synchronizedmap、concurrentmap中

 

将元素放到vector、copyonwriteArrayList、CopyOnwriteArraySet、synchronizedlist、synchronizedset

 

将元素放到 blockingQueue、concurrentlinkedQueue

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics