多线程访问同一个对象,不可避免可能会带来“临界资源”被分割的问题,本来一个代码块或者说一个线程完整的执行完,才到另一个线程执行,但是如果时间片到期了,又有很多线程频繁访问,就会有问题。
同步代码块
给对象增加一个lock属性,然后利用synchronized(lock){ }锁住完整的代码块,synchronized就像一把锁,lock是锁标记,方法有所标记,对象也有锁标记:
class MyStack{
char[] data = {'A', 'B', ' '};
int index = 2;
public void push(char ch){
synchronized(this){
data[index] = ch;
try{
Thread.sleep(1000);
}catch(Exception e){}
index ++;
}
}
例如上面的this其实就是本对象。
同步方法
像上面的例子,对“this”加锁就相当于同步方法了,用synchronized作为方法的修饰符来表达同一个意思
public synchronized void push(char ch) { //synchronized用作方法的修饰符
data[index] = ch;
try{
Thread.sleep(1000);
}catch(Exception e){}
index ++;
}
public synchronized void pop(){ //这个也是一样的,都要加上这个关键词才完整
index --;
data[index] = ' ';
}
小结
一般来说,用最多的是同步方法,即用synchronized修饰符修饰方法,当一个线程在访问这个对象的同步方法时,其他的线程不能再访问这个对象中的任何的同步方法,所以一个对象内肯定不止有一个同步方法。