javaSE 笔记 同步代码块 + 同步方法 + 线程安全类(String,vector,hashtable) + Lock锁

同步代码块解决数据安全问题

出现数据安全问题的原因:

1.是否是多线程环境
2.是否有共享数据
3.是否有多余操作共享数据

解决思路:把多条语句操作共享数据的代码给锁起来,让任一时刻只能有一个线程执行即可。
在java中,提供了同步代码块,锁多条语句操作共享数据,格式如下:

synchronized(任意对象){
多条语句操作共享数据的代码
}

synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁,例子中的对象用的是new的一个Object对象,
不过要注意的是如果直接在括号里面new,那么每个线程运行到synchronized的时候,都有一把锁,那么就相当于有了三把锁,这样的话是锁不住的,所以应该把锁声明在外面,比如private Object obj = new Object(); 然后用obj放在原来的那个任意对象里,这样就是多个进程被一把锁锁住了
同步的好处与弊端:

好处:解决了多线程的数据安全问题。
弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

同步方法

就是把synchronized关键字加到方法上
格式:修饰符 synchronized 返回值类型 方法名(方法参数) { }
这边的synchronized的锁后面没加对象,那么他的锁是什么呢?是 this ,所以之前的锁也必须改成this

同步静态方法:就是把synchronized关键字加到静态方法上
格式:修饰符 static synchronized 返回值类型 方法名(方法参数)
静态方法的锁又是什么呢?是跟类自身有关的,类名.class具体的后面会讲

线程安全的类

StringBuffer
不考虑线程安全,使用StringBuilder替代,而且他更快
vector
不考虑线程安全,使用ArrayList替代
Hashtable
不考虑线程安全,使用HashMao替代
不过一般来说StringBuffer在多线程中会被使用,但是vector和Hashtable一般不被使用,因为被替代了。
vector被Collections.synchronizedList(new ArrayList())替代,Hashtable也是被Collections中对应的map方法
给替代了。

Lock锁

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作
Lock中提供了获得锁和释放锁的方法 void lock():获得锁 void unlock():释放锁
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
看代码的话加锁和解锁很方便,不过有个需要注意的是,如果加锁部分的代码出现问题,解锁代码就不会被执行了,所以说用了try...finally操作
需要把解锁的操作放在finally中。

posted @ 2021-09-02 12:38  Lanezzz  阅读(95)  评论(0)    收藏  举报