什么是线程间的共享
Java支持多个线程同时访问一个对象或一个对象里的成员变量。
线程间共享会存在的问题
- 当多个线程处理同一块内存区域时,由于对共享内存的操作不是原子操作,会造成语句的执行得不到期望的结果。
public class Test{
private Object obj = new Object();
private int count = 0;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
private void add(){
count++;
}
}
private static class Count extends Thread{
private Test test;
public Count(Test test){
this.test = test;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
test.add();
}
}
}
public static void main(String[]args){
Test test = new Test();
Count countOne = new Count(test);
Count countTwo = new Count(test);
countOne.start();
countTwo.start();
Thread.sleep(100);
System.out.println(test.count);
}
运行结果在1000~2000之间。
synchronized关键字
为了解决上面的问题Java语言内置了synchronized关键字,所以也叫内置锁。
- 它可以保证同一时刻只有一个线程处于方法或同步块中。
解决上面的问题可以采用如下两种方式,即对象锁
。
//①锁的是当前对象
private synchronized void add(){
count++;
}
//②锁的是指定对象
private void add(){
synchronized(obj){
count++;
}
}
- 类锁 实际锁的是class对象
private static synchronized void add(){
count++;
}
其实本质上还是对象锁,只不过类锁是由static关键字修饰的成员变量或方法上,虚拟机中只有一份。
网友评论