java并发(一)线程安全概念

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qwkxq/article/details/57110587

java中包含几种线程级别:

不可变:这种级别是最简单的线程安全方式,即:如果带有状态的变量是基本数据类型定义成final,是引用类型,则其对象不能有改变自身的行为
(如String,enum,Number的部分子类:Integer,Long等[不包括AtomicInteger,AtomicLong等])

绝对安全:不论运行环境如何,调用者都不需要任何额外的措施来保证线程安全,要想达到这点,可能会付出巨大的代价。

相对安全:对对象的单独操作是线程安全的(如上面多线程访问remove方法,add方法),但对于特定顺序的连续调用,就需要调用者使用额外的同步手段来保证线程安全。

以java.util.Vector举例,在java中称它为线程安全的对象,这是因为Vector中所有的行为都被synchronized修饰,这也是java通俗意义上讲的线程安全的概念,然而Vector实际上只是线程相对安全的,并非绝对安全,在涉及特定顺序的连续调用就会出现问题:

/*
此程序先对Vector初始化1000个元素,然后每次开启2个线程,1个线程执行删除元素操作,1个线程执行获取元素操作。
 当一个错误的时机(获取线程进入for循环执行到当前Vector的size-x时,被删除线程抢走执行权删除了x个或以上的元素)
 此时获取线程才得到执行权,结果此前的Vector的长度已经不够size-x,就会导致角标越界异常。
*/
private static Vector<Integer> v = new Vector<>();
    static{
        for(int i=0; i<1000; i++){
            v.add(i);
        }
    }
    public static void main(String[] args) {
        while(true){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0; i<v.size(); i++){
                        v.remove(i);
                    }
                }
            }).start();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i=0; i<v.size(); i++){
                        v.get(i);
                    }
                }
            }).start();


            //不要产生过多的线程,防止操作系统假死
            if(Thread.activeCount()>20)break;
        }
    }

线程兼容:指对象本身不是线程安全的,但是调用者可以通过正确的同步手段来保证线程安全,也就是我们通常说的线程不安全。

线程对立:指对象无论是否采用同步操作,都无法在多线程中并发使用的代码,由于java天生具备多线程特性,这种情况很少见,且通常是有害的,应当尽量避免。
(常见的有Thread对象的resume方法和suspend方法[已废弃],System的setIn,setOut,runFinalizersOnExit)

猜你喜欢

转载自blog.csdn.net/qwkxq/article/details/57110587
今日推荐