并发对于程序来讲,并不安全。
多个线程同时对一个共享资源进行读写时,可能会发生错误。
如何避免这样的问题?
1.synchronized关键字
被synchronized关键字修饰的域,将被“上锁”,在程序执行这段代码时,只能有一个线程执行这段任务,在该线程没有执行完成之前,其他线程将等待该线程执行完成。
synchronized可以修饰普通方法:synchronized void a();
也可以修饰静态方法:synchronized static void a();
还可以修饰一个普通代码块,这个代码块被称为临界区:synchronized(对象){};
2.Lock接口
其实现类为ReentrantLock,Lock接口中有几个重要的方法:
1.lock()获取对象锁,如果锁被其他线程获取,线程等待
2.trylock()具有boolean返回值,获取锁返回true,没有返回false,在没有获取到对象锁时,不会等待,直接返回值。
3.trylock(参数)和没有参数的一样,区别在于,在没有得到参数是,等待参数时间,参数时间过后,返回值。
4.unlock()释放对象锁,使用Lock接口必须显示的创建Lock对象,获取锁,和释放锁。
Lock对象和try-finally相配合,在try块中写入被锁的内容,在finally中释放锁。
3.volatile关键字
volatile关键字确保了可见性。
什么是可见性?
可见性是当一个线程修改了一个共享资源的值后,其他的线程都能看见这个值被改变。
用我的理解就是,当值改变了,不管是在修改线程之前调用的,还是在修改线程之后调用的,只要这个线程还持有这个共享资源,他的值都被改变了。