java 初入多线程6

作者: 胖琪的升级之路 | 来源:发表于2017-09-24 23:12 被阅读33次

线程安全的概念 与synchronized

  1. 多线程在处理的过程中如果我们没有给程序进行过任何处理的话,在执行的过程中可能会出现多个线程对同一个数据同时进行修改,那么就可能会出现就修改一次的情况。比如程序中有i++,这个操作那么在执行过程中可能就会出现修改一次的情况。
多线程冲突

为了防止多线程操作出现问题,我们必须保证多个线程对线程不安全的数据访问完全同步。在Java 中提供了一个关键字synchronized来实现这个功能。

  1. 关键字synchronized 的作用就是实现线程之间的同步,对需要同步的代码加锁,实现 只有一个线程进入同步代码块中。来保证线程间的安全性。大概有以下几种用法
  • 指定加锁对象,就是利用指定的对象在进入代码块之前获得 该对象。
  • 直接作用于实例方法上:利用当前的实例进行加锁,new 之后的对象
  • 直接作用于静态方法:对当前类加锁。 类变量。
  1. 如果程序中本来数据进行的都是正数操作,预期都是正数的话,那么如果出现负数,那么可能出现这个情况,可能就是内存溢出导致的问题。比如long 型 如果超过最大值那么就会变成负数。 这就是内存溢出的问题。线上有时候就会碰到该问题。。需要注意。

并发下的ArrayList

    static ArrayList<Integer> al=new ArrayList<Integer>(10); 
    
    public static class AddThread implements Runnable{

        public void run() {
            for(int i= 0; i<1000000; i++) {
                al.add(i);
            }
            
        }
    }
    
    public static void main(String[] args) throws Exception {
        Thread t1 =new Thread(new AddThread());
        Thread t2 =new Thread(new AddThread());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(al.size());
    }
}
  • 这个代码执行完毕后,可能出现三种结果。
  1. 正常结束,大小为200000.。
  2. 出现异常的情况。下标越界情况
下标越界

这是因为ArrayList 在扩容的时候 ,内部的一致性被破坏掉。因为ArrayList 是线程不安全的,没有锁机制,导致在多个线程访问的时候 出现了不一致的内部状态,导致出现下标越界

  1. 出现一个隐蔽的错误就是没有出现下标的越界的情况 ,只给了一个大小的值。出现这个情况的原因是多个线程在进行赋值的时候,对同一个位置进行赋值,在这种情况下 就没有错误提示。我们可以使用Vector 带起ArrayList.

hashMap 诡异的错误

  1. hashMap 同样也不是线程安全的 。会出现如下结果
  • 程序正常运行结果也符合预期。
  • 程序正常结束,但是不符合预期,小于我们需要的数据大小
  • 程序永远不会结束
  1. 在验证过程中我们可以使用jps 命令来查看当前系统中java 的进程。如果想看具体 使用 可以使用 jps -help 有命令介绍。 这个是在linux上使用 一般会用jps -ml 显示内容和名称
  2. 在使用jps 后我们可以看到端口号 。然后使用jstack +端口号来看我们的运行的线程。
  3. java7线面的源码hashMap ,java8现在已经不是该循环


    java7HashMap.png

    解决方案可以使用ConCurrentHashMap代替

错误的加锁问题

  1. 在使用加锁的时候。我们不要使用锁对象是Integer ,String 这中对象去作为一个锁,可能造成加锁没有加成功的时刻,因为如果我们在其他地方对其修改后,该对象的地址就会变成新的对象。那么锁就会失去作用。

相关文章

  • java 初入多线程6

    线程安全的概念 与synchronized 多线程在处理的过程中如果我们没有给程序进行过任何处理的话,在执行的过程...

  • java初入多线程4

    线程中断 概念 :让目标线程停止执行,但是是高知目标线程希望线退出,具体退出由目标线程自己决定。 相关的方法,暂时...

  • java初入多线程17

    使用Disruptor 实现消费者和生产者 我们在主方法操作中将缓冲区设置成1024 , 在这里有四个消费者, 有...

  • java初入多线程11

    核心线程池的内部实现机制。 阿里巴巴 code检验推荐自己实现线程池的创建。不是使用Executors的创建方法。...

  • java初入多线程12

    自定义线程创建:ThreadFactory 我们原先用的线程池ThreadPoolExecutor 里面的线程都...

  • java初入多线程10

    线程阻塞工具类 :LockSupport LockSupport 是一个非常实用的线程阻塞工具, 可以在线程内任意...

  • java初入多线程7

    同步控制 synchronized 扩展:重入锁 重入锁来代替synchronized,在Jdk1.6以后 syn...

  • java初入多线程14

    接下来几章说的是锁的优化和注意事项问题。 减小锁持有的时间 对于在方法执行的过程中有的步骤不需要进行同步,那么就在...

  • java初入多线程15

    无锁的线程安全整数: AtomicInteger 方法介绍public final int get(); 取得当前...

  • java初入多线程13

    并发集合简介 ConcurrentHashMap : 线程安全的HashMap; CopyOnWriteArray...

网友评论

    本文标题:java 初入多线程6

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