java回顾之多行代码的线程安全问题以及并发包
一、线程安全问题
1.1、多行代码执行顺序的问题
产生的原因就是多个线程操作了共享的数据
解决办法使用synchronized关键字
1.2、synchronized关键字
synchronized关键字表示同步或串行化,将多行代码当成是一个整体,一个线程进入这个代码块中,只有全部执行完毕结束后,其他线程才会执行。
同步代码块
格式
synchronized(锁){ 锁可以是任何类型的对象,多个线程使用同一个锁对象
共享的数据放在里面
}
同步方法
将关键字加在方法上,就是同步方法
//非静态同步方法 public synchronized void method(){ 锁对象是当前类的this对象 } 非静态方法往往是本对象创建出来了 //静态同步方法 public static synchronized void method(){ 锁对象是当前类的字节码对象 XXX.class }
静态方法都是对象共享的,还用对象的话,地址不同,锁就失效了,这是原理,方法直接用就行
二、lock锁
两个方法,加锁和解锁 lock()和unlock()解锁
这里注意之所以在if里面加解锁,是因为break就结束了,不加的话其他线程进不来,同时注意这是非公平锁,线程会不但的插队,数据太少,线程太少,效果可能演示不出来,一个线程一直插队,自己就全跑完了。
二、并发包
2.1
每个方法全都是同步的,当任意一个方法在执行时,别的方法都不能执行。
CAS + 局部(synchronized)锁定
Hashtable执行的速度慢
ConcurrentHashMap执行效果快
三、
new CountDownLatch(int count)// 初始化一个指定计数器的CountDownLatch对象
void await() // 让当前线程等待
void countDown() // 计数器进行减1,如果减到0等待的线程就会执行
四、
public Semaphore(int permits) //permits 表示许可线程的数量
public Semaphore(int permits, boolean fair) //fair 表示公平性,如果这个设 为 true 的话,下次执行的线程会是等待最久的线程
五、
new Exchanger() //构造方法,创建对象
V exchange(V x) //参数是给对方的数据,返回值是对方发来的数据