目录
同步锁作用
当多个线程需要使用某个资源,并且该资源同一时间只能被一个线程使用时,就需要用同步锁来协调各个线程。保证同一时间只有一个线程使用该资源。
以生产者、消费者线程为例:
生产者线程和消费者线程共用一个对象集。当生产者线程发现对象集中没有对象时,立即加入一个对象并通知消费者线程。而消费者线程被唤醒后检查是否有一个对象,如果有就立即取出。保持对象集中的数量为0或者1。
使用方法
将需要单独使用线程的代码用synchronized括起来。小括号里是需要锁定的对象集。生产者和对象者使用的是同以对象集。所以小括号里括的是一样的。
注意!要用try {} catch (Exception e) {}将下面代码括起来,否则报错。
synchronized(ObjectList) {
ObjectList.add(new Object());//ObjectList.remove(0);
}
这样可以保证同一时间只能有一个线程对对象集进行操作。如果到此你还有点似懂非懂的感觉,不妨看看下面的部分分析分析代码运行的过程。
代码运行的顺序
假定生产者负责培训好(放入)程序员,消费者负责招聘(取走)程序员,而对象集中存的就是程序员。
对象集中的对象
public class Programmer {
int id;
String name;
public String toString(){
return name+id;
}
}
生产者代码,为了省事就省略构造器等结构了,只放run()函数
public void run() {
while (flag) {
try {
synchronized(programmerList) {
while (programmerList.size()>0) {
programmerList.wait();
}
while(programmerList.size()<=0){
Programmer programmer=new Programmer();
programmerList.add(programmer);
programmerList.notify();
}
}
} catch (Exception e) {e.printStackTrace();}
}
}
生产者线程运行到在while (programmerList.size()>0) {}循环中如果条件不满足运行到programmerList.wait();时线程暂停,释放资源;等待被通知后继续一次while循环判断条件是否满足,条件满足即跳出循环。在生产者线程加入一个对象后立即通知别的等待线程即消费者线程。此时消费者线程并不立即获得对象集,因为生产者线程还在synchronized(programmerList) {}代码块中。那什么时候消费者线程才可以获得对象集呢?
当生产者线程在while(programmerList.size()<=0){}循环第二次运行时发现programmerList.size()=1了,不满足条件,于是跳出while(programmerList.size()<=0){}循环,接着跳出synchronized(programmerList) {}代码块。此时消费者线程可以获得对象集了吗?只能说有可能获得,因为此时生产者线程可能继续进入下一个while (flag) {}后很快进入synchronized(programmerList) {}代码块中,于是消费者线程仍不能得到对象集。但很接近了,一旦生产者线程在while(programmerList.size()>0){}循环中发现programmerList.size()=1了便运行programmerList.wait();代码,于是生产者线程释放资源,消费者线程开始从消费者线程的programmerList.wait();的下一句代码开始运行。
消费者代码
public void run() {
while (flag) {
try {
synchronized (programmerList) {
while (programmerList.size() <=0) {
programmerList.wait();
}
while (programmerList.size() > 0) {
programmerList.remove(0);
programmerList.notify();
}
}
} catch (Exception e) {e.printStackTrace();}
}
}
消费者线程的过程和生产者差不多,就不重复分析了。