packagecom.joysuch.testng.thread;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.locks.ReentrantLock;importcom.joysuch.testng.thread.ThreadDemo2.CarHouse.Car;/***@authorning
* 创建于 2017年11月22日上午11:25:29
* //TODO (加上互斥锁)*/
public classThreadDemo2 {/***@authorning
* 创建于 2017年11月22日上午11:27:53
* //TODO 卖车的当做生产者线程*/
public static class CarSeller implementsRunnable {privateCarHouse carHouse;publicCarSeller(CarHouse carHouse){this.carHouse =carHouse;
}
@Overridepublic voidrun() {for (int i = 0; i < 10; i++) {//当做生产者线程,往仓库里边增加汽车,其实是触发增加汽车
carHouse.put(i);
}
}
}/***@authorning
* 创建于 2017年11月22日上午11:29:00
* //TODO 购买者当做消费者线程*/
public static class Consumer implementsRunnable {privateCarHouse carHouse;publicConsumer(CarHouse carHouse){this.carHouse =carHouse;
}
@Overridepublic voidrun() {for (int i = 0; i < 10; i++) {//当做消费者线程,从仓库里边提取汽车,其实是触发,从仓库里边提取一辆汽车出来
carHouse.get(i);
}
}
}/***@authorning
* 创建于 2017年11月22日上午11:30:22
* //TODO 汽车仓库*/
public static classCarHouse {/*** 车库中汽车数量*/
public Integer carNums = 0;/*** 存放汽车的集合*/
public List carList = new ArrayList<>();publicInteger getCarNums() {returncarNums;
}public voidsetCarNums(Integer carNums) {this.carNums =carNums;
}public ListgetCarList() {returncarList;
}public void setCarList(ListcarList) {this.carList =carList;
}//直接增加上synchronized关键字方式,成员方法,锁的是当前bigHouse对象//这种锁是互斥锁,方法在同一个时刻,只有一个线程可以访问到里边的代码
/*public synchronized int put(int i) {// 提供给生产者放汽车到仓库的接口
Car car = CarFactory.makeNewCar();
carList.add(car);// 加到仓库中去
carNums++;// 总数增加1
System.out.println("生产汽车-" + i + "->车库汽车数量---count = " + carList.size());
return carList.size();
}
public synchronized int get(int i) {// 提供给消费者从这边取汽车接口
Car car = null;
if (carList.size() != 0) {// size不为空才去取车
car = carList.get(carList.size() - 1);// 提取最后一个car
carList.remove(car);// 从从库list中移除掉
carNums--;// 总数减少1
}
System.out.println("消费汽车-" + i + "->车库汽车数量---count = " + carList.size());
return carList.size();
}*/
//Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock更灵活的结构,有很大的差别,并且可以支持多个Condition对象 Lock是控制多个线程对共享资源进行访问的工具。//通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁, 线程开始访问共享资源之前应先获得Lock对象。//不过某些锁支持共享资源的并发访问,如:ReadWriteLock(读写锁),在线程安全控制中, 通常使用ReentrantLock(可重入锁)。使用该Lock对象可以显示加锁、释放锁。
final ReentrantLock lock = newReentrantLock();public int put(inti){int size = -100;//上锁
lock.lock();try{
Car car=CarFactory.makeNewCar();
carList.add(car);
carNums++;
size=carList.size();
System.out.println("生产汽车-" + i + "->车库汽车数量---count = " +size);
}finally{//释放锁
lock.unlock();
}returnsize;
}public int get(inti){//上锁
int size = -100;
lock.lock();try{
Car car= null;if (carList.size() != 0) {//size不为空才去取车
car = carList.get(carList.size() - 1);//提取最后一个car
carList.remove(car);//从车库list中移除掉
carNums--;//总数减少1
}
size=carList.size();
System.out.println("消费汽车 " + i + "-->车库汽车数量---count = " +size);
}finally{//释放锁
lock.unlock();
}returnsize;
}public static classCar {publicString carName;public doublecarPrice;publicCar(){}publicCar(String carName, Double carPrice){this.carName =carName;this.carPrice =carPrice;
}publicString getCarName() {returncarName;
}public voidsetCarName(String carName) {this.carName =carName;
}public doublegetCarPrice() {returncarPrice;
}public void setCarPrice(doublecarPrice) {this.carPrice =carPrice;
}
@OverridepublicString toString() {return "Car [carName=" + carName + ", carPrice=" + carPrice + "]";
}
}
}/*** 采用静态工厂方式创建car对象,这个只是简单模拟,不做设计模式上的过多考究*/
public static classCarFactory {privateCarFactory(){
}public staticCar makeNewCar(String carName, Double carPrice){return newCar(carName, carPrice);
}public staticCar makeNewCar() {return newCar();
}
}/*** 第一个版本的生产者和消费者线程,没有加上同步机制的演示例子
*
*@paramargs*/
public static voidmain(String[] args) {int x = 0;//这里为了便于查看测试结果,所以执行了多次
while(x < 50){
CarHouse bigHouse= newCarHouse();new Thread(newCarSeller(bigHouse)).start();new Thread(newConsumer(bigHouse)).start();try{
Thread.sleep(500);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(bigHouse.getCarNums());
System.out.println(bigHouse.getCarList().size());
x++;
}
}
}