美文网首页
Java并发访问

Java并发访问

作者: 极客天空 | 来源:发表于2020-04-19 19:32 被阅读0次

1 线程安全

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

2 局部变量并不会数据共享

局部变量,不同线程的并不共享,所以并不会发生覆盖

PrivateNum p=new PrivateNum();
        MyThread threadA=new MyThread('A',p);
        MyThread threadB=new MyThread('B',p);
        threadA.start();
        threadB.start();

public void test( char i) {
 
            try {
             int num=0;
             - - - - - - -
            }
         catch (InterruptedException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }}

3 实例成员变量数据共享

PrivateNum p=new PrivateNum();
        MyThread threadA=new MyThread('A',p);
        MyThread threadB=new MyThread('B',p);
        threadA.start();
        threadB.start();
public void test( char i) {
            int num=0;
            try {
             - - - - - - -
            }
         catch (InterruptedException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }}

线程AB访问的是同一个变量(指向同一个地址),所以这个时候会发生覆盖,同时这里出现了线程安全问题

4 synchronized关键字可以避免线程安全问题

  • 如果多个线程访问的是同一个对象方法中的局部变量,那么这个变量并不共享,线程AB对此变量的操作将互不影响
  • 如果多个线程访问的是同一个对象方法中的成员变量,那么这个变量共享,如果不处理好线程问题,可能会出现线程安全问题
  • 通过synchronized关键字可以使方法同步

5 多个线程访问的是两个不同实例的同一个同步方法

public static void main(String[] args) {
        PrivateNum p1=new PrivateNum();
        PrivateNum p2=new PrivateNum();
        MyThread threadA=new MyThread('A',p1);
        MyThread threadB=new MyThread('B',p2);
        threadA.start();
        threadB.start();
    }}

这是因为这里是两个锁,创建了p1和p2对象,创建的是两个锁,锁对象不同不造成互斥作用

6 多线程调用同一个实例的两个不同(一个同步,一个非同步)方法

MyThread threadA=new MyThread('A',p1);
        MyThread2 threadB=new MyThread2('B',p1);
        threadA.start();
        threadB.start();

线程B可以异步调用非同步的方法

7 死锁

线程AB开始执行时,因为锁不同,所以不互斥,A当执行到另一个同步代码块(锁2)的时候,由于这个时候锁给线程B占有了,所以只能等待,同样B线程也是如此,AB互相抢对方的锁,但是所以造成了死锁

8 总结

  • 多个线程调用的不同实例的同步方法,线程不互斥。
  • 如果两个线程的锁对象一样(都是p1),两个线程分别调用同步方法和非同步方法,线程不会同步执行。
  • 但是如果调用两个不同的同步方法,因为锁对象一致,两个线程同步执行。
    设想一个情况,有一个实例有两个方法,一个修改值(synchronized),一个读值(非synchronized),此时两个线程一个修改值,一个读取值,这个时候因为这两个线程并不会挣抢锁,两个线程互不影响,那么此时可能就会出现一种情况,线程A还没修改完,线程B就读取到没有修改的值。这就是所谓的脏读。
  • 重入锁,一个获得的锁的线程没执行完可以继续获得锁。
  • 线程占用锁的时候,如果执行的同步出现异常,会将锁让出。
  • 父类方法同步,子类重写该方法(没有synchronized关键字修饰),是没有同步作用的。
  • 同步代码块的锁对象可以是本对象,也可以是其他对象。同一个锁对象可以产生互斥作用,不同锁对象不能产生互斥作用
  • 一个方法中有同步代码块和非同步代码块,同步代码块的代码是同步执行的(块里的代码一次执行完),而非同步代码块的代码可以异步执行
  • 一个对象中的不同同步代码块是互斥的,执行完一个代码块再执行另一个代码块
  • 同步代码块(this)和synchronized方法的锁定的都是当前对象 this
  • Class类也可以是锁,Class锁的实现可以通过静态的synchronizd方法,也可以通过静态方法里面的同步代码块(锁对象为Class)
  • 静态类的同步方法锁对象还是该类的一个实例

volitate增加了实例变量在对个线程之间的可见性,保证我们获得的是变量的最新值。
volatile在读上面保持了同步作用,但是在写上面不保持同步
synchronized的同步作用不仅保证了对同一个锁线程的互斥,还保证了数据的同步
volatile对比synchronized
两者修饰的不同,volatile修饰的是变量,synchronized修饰的是方法和代码块
两者的功能不同。volatile保证数据的可见性,synchronized是线程同步执行(间接保证数据可见性,让线程工作内存的变量和公共内存的同步)
volatile性能比synchronized性能高

相关文章

  • Java并发访问

    1 线程安全 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行...

  • java并发中CountDownLatch的使用

    java并发中CountDownLatch的使用 在java并发中,控制共享变量的访问非常重要,有时候我们也想控制...

  • Java并发教程

    Java并发教程 Java并发概述Java并发环境设置Java并发主要操作Java并发性线程间通信Java并发同步...

  • 深入解析Java AtomicInteger 原子类型

    深入解析Java AtomicInteger原子类型 在进行并发编程的时候我们需要确保程序在被多个线程并发访问时可...

  • 线程相关问题

    常用并发多线程包 java.util.concurrent synchronized 可重入性 子类可以访问父...

  • Java面试重难点剖析(不断更新)

    Java面试重难点剖析(不断更新) 1、高并发访问数据库优化方法 2、 java finalize方法总结、GC执...

  • java并发(二)线程安全性与Java内存模型

    谈到并发,首先要提到的就是安全,所有的并发编程的前提都是安全。在java中, 什么是线程安全性?在多线程并发访问一...

  • Java并发编程之CAS

    在Java并发编程的世界里,synchronized 和 Lock 是控制多线程并发环境下对共享资源同步访问的两大...

  • Java并发 - 并发编程实战

    Java并发 - 线程Java并发 - 线程池Java并发 - Executor/ExecutorService/...

  • Nginx Tomcat集群配置

    并发访问 对于服务器来说,大量的并发访问容易造成服务器宕机 并发访问性能测试 可以通过压力测试来检查高并发访问的性...

网友评论

      本文标题:Java并发访问

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