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

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