线程安全问题:
以计算机来说,在计算机系统中,系统资源分配的单位被称为进程,而在同一个进程计算机允许多个线程并发执行,并且多个线程能够共享进程范围内的资源,如内存地址等。但是,当多个线程当多个线程并发访问同一个内存地址并且内存地址保存的值是可变的时候就有可能会发生线程安全问题,因此需要内存数据共享机制来保证线程安全问题。
引起线程安全问题的原因:
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。
下面是一个案例,我们对id进行操作,会发现这里id每次答案都不是一样的,(我注解掉的地方是给加了锁的)。
package com.openlab.day24;
public class TestThread03 {
public static void main(String[] args) {
MyThread06 mt = new MyThread06();
Thread m1 = new Thread(mt);
Thread m2 = new Thread(mt);
m1.start();
m2.start();
}
}
class MyThread06 implements Runnable {
private int id;
private Object key = new Object();
// @Override
// public void run() {
// for (int i = 0; i < 1000000; i++) {
// synchronized (key) {
// id++;
// }
// }
// System.out.println(Thread.currentThread().getName() + "--结果是:"+ id);
// }
@Override
public synchronized void run() {
for (int i = 0; i < 1000000; i++) {
id++;
}
System.out.println(Thread.currentThread().getName() + "--结果是:"+ id);
}
}
2、解决多线程并发访问资源安全问题的方法:
(1)synchronized
synchronized关键字,就是用来控制线程同步的,保证我们的线程在多线程环境下,不被多个线程同时执行,确保我们数据的完整性,使用方法一般是加在方法上。
(2)Lock
Lock是在Java1.6被引入进来的,Lock的引入让锁有了可操作性,是指我们在需要的时候去手动的获取锁和释放锁,从使用上synchronized使用起来比Lock更方便。(现在我们建议使用synchronized)。