对象锁
synchronized理解
Java运行系统为每一个对象分配了唯一的对象锁。任何线程访问一个对象中被同步的方法前,首先要取得该对象的对象锁
同步方法被执行后,线程会释放对象的对象锁
可重入锁:Java运行系统允许一个线程再次取得已为自己控制的对象锁
wait和notifyAll方法理解
wait方法使得当前线程进入阻塞状态,同时交出对象锁,从而其他的线程可以取得对象锁
notifyAll方法唤醒的是由notifyAll方法所在的对象而进入等待状态的所有线程
然后被唤醒的线程会去竞争对象锁,当其中的某个线程取得锁之后,其他的线程重新进入阻塞状态
生产者消费者模式Java模拟代码
public class HelloWord {
public static void main(String[] args) {
Box b = new Box();;
new Thread(new Producer(b,"P")).start();
new Thread(new Customer(b,"C")).start();
}
}
class Box{
//当avaliable为假的时候放进去数据;为真的时候可以拿数据
private boolean available = false;
public int value = 0;
public synchronized int get(){
while(available==false){
try {
//等待生产者写入数据
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
available = false;
//通知生产者数据已经被取走,可以重新写入数据
notifyAll();
return value;
}
public synchronized void put(int value){
while(available==true){
try {
//等待消费者取走数据
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.value = value;
//通知消费者可以来取数据
available = true;
notifyAll();
}
}
//生产者
class Producer implements Runnable{
private Box b = null;
private String name = null;
public Producer(Box b,String name){
this.b = b;
this.name = name;
}
@Override
public void run() {
Thread current = Thread.currentThread();
for(int i=1;i<6;i++){
b.put(i);
System.out.println("Producer "+name+"produce "+i);
try {
current.sleep((int)Math.random()*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Customer implements Runnable{
private String name;
private Box b;
public Customer(Box b,String name){
this.b = b;
this.name = name;
}
@Override
public void run() {
// TODO Auto-generated method stub
Thread current = Thread.currentThread();
for(int i = 1;i<6;i++){
b.get();
System.out.println("Customer "+name+"customer "+b.get());
try {
current.sleep((long)Math.random()*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}