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

来源:互联网 发布:全国网络统考系统 编辑:程序博客网 时间:2024/05/17 23:57

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)

0 0