线程安全 JVM内存中的堆区,是一个共享的区域,是所有线程都可以访问的内存空间。 运行结果为下图 可以看出预期与结果不符 t1线程操作一下变量num,然后时间片用完退出去,t2先过来又操作了变量num, 等t1线程再过来的时候,这值已经被t2线程给“偷偷”修改了,那么就出现了和预期不符的情况 出现数据结果和预期不符的情况,这种情况就是线程安全问题。 1. 多个线程并发运行 2. 访问同一个共享变量 3. 具有写操作 Java中提供了线程同步的机制,来解决上述的线程安全问题。 例如,将上面的有安全问题的代码进行改造,给需要同步的代码使用synchronized加锁 运行结果如下图 线程同步的效果,就是一段加锁的代码,每次只能有一个拿到锁的线程,才有资格去执行,没有拿到的锁的线程,只能等拿到锁的线程把代码执行完,再把锁给释放了,它才能去拿这个锁然后再运行代码。 这样以来,本来这段代码是俩线程并发访问,“争先恐后”的去执行的,现在线程同步之后,这段代码就变成了先又一个拿到的锁的先去执行,执行完了,再由另一个线程拿到锁去执行。 相当于是大家每个线程不要抢,排好队一个一个去执行,那么这时候共享的变量的值,肯定不会出现线程安全问题
JVM内存中的栈去,是线程的私有空间,每个线程都有自己的栈区,别的先无法访问到自己栈区
的数据。
如果代码只有一个main线程,只有它自己去访问堆区中的对象数据,自然没有什么问题,但是在多线程的环境中,如果有两个线程并发访问堆区中一个对象中的数据,那么这个数据可能就会出现和预期结果不符的情况。
举例来说
此时内存图为:
一般线程安全问题都会包含以下三个条件
Java中实现线程同步的方式,是给需要同步的代码进行 synchronized 关键字加锁