线程安全和非线程安全的区别是什么?

TheDisguiser 2020-05-26 22:05:44 java常见问答 11107

相信经过前几次的讲解,大家都对线程安全有了一定的了解,但你们知道线程安全与非线程安全有哪些区别吗?快跟我来了解下吧

线程安全与非线程安全区别

一、线程安全

所谓线程安全,就是指在多线程访问时数据时,采用加锁机制,当一个线程访问该类的某个数据时,就会进行保护,其他不相干的线程就不能够访问,除非该线程读取完毕,其他线程才可读取。这样就不会出现数据不一致或者数据污染。

线程安全保证了多线程同时操作同一个对象不会出现问题。

线程安全会使用很多synchronized关键字来进行同步控制,所以必然会导致性能大幅的降低。

二、非线程安全

线程不安全就是在运行中不提供数据访问保护,这样就可能出现多个线程先后更改数据,造成所得到的数据是脏数据。

非线程安全指多线程操作同一个对象可能会出现问题。

其他:

ArrayList是非线程安全的,Vector是线程安全的

HashMap是非线程安全的,HashTable是线程安全的

StringBuilder是非线程安全的,StringBuffer是线程安全的

ArrayList:底层是数组结构,查询快,增删慢

LinkedList:底层结构是链表,查询慢,增删快

线程安全实现

实例:

public class ThreadSafe
{
    public static void main(String[] args)
    {
        HasSelf numself = new HasSelf();
        threadA aThreadA = new threadA(numself);
        aThreadA.start();
        threadB bThreadB = new threadB(numself);
        bThreadB.start();
    }
}
class HasSelf
{
    //private int num=0;
    public void addI(String username)
    {
        try
        {
            int num = 0;
            if (username.equals("a"))
            {
                num = 100;
                System.out.println("a set over");
                Thread.sleep(1);
            }
            else
            {
                num = 200;
                System.out.println("b set over");
            }
            System.out.println(username + "num= " + num);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
class threadA extends Thread
{
    private HasSelf numself;
    public threadA(HasSelf numself)
    {
        super();
        this.numself = numself;
    }
    @Override
    public void run()
    {
        super.run();
        numself.addI("a");
    }
}
class threadB extends Thread
{
    private HasSelf numself;
    public threadB(HasSelf numself)
    {
        super();
        this.numself = numself;
    }
    @Override
    public void run()
    {
        super.run();
        numself.addI("b");
    }
}

执行结果:

a set over
b set over
anum= 100
bnum= 200

线程非安全:

注释sleep

结果:

a set over
anum= 100
b set over
bnum= 200

把//private int num=0;注释去掉,把int num=0注释掉

执行结果:

a set over
b set over
bnum= 200
anum= 200

注:多个线程共同访问一个对象中实例变量时,可能出现非线程安全,同时若线程访问多个实例变量,可能产生交叉情况。

以上就是今天的全部内容了,想知道更多有关java常见问答的知识,就请持续关注咱们的网站吧。

推荐阅读:

线程安全的list该如何实现?

线程安全的类在java中有几种?如何成为线程安全类?

java线程安全如何实现?有哪些实现方法?