复习一下多线程
Customer.java
package com.example;
public class Customer implements Runnable{
private Depository depository;
public void setDepository(Depository depository) {
this.depository = depository;
}
@Override
public void run() {
while(true) {
depository.takeGood();
}
}
}
Productor.java
package com.example;
public class Producter implements Runnable{
private Depository depository;
@Override
public void run() {
while(true) {
depository.addGood();
}
}
public void setDepository(Depository depository) {
this.depository = depository;
}
}
Depository.java
package com.example;
public class Depository {
private int count;
public synchronized void takeGood() {
if(count<=0) {
try {
System.out.println("It's empty!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
Thread.currentThread().sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
notifyAll();
System.out.println(Thread.currentThread().getName()+" take a good");
viewGoods();
}
}
public synchronized void addGood() {
if(count>=20) {
try {
System.out.println("It's full!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
notifyAll();
System.out.println(Thread.currentThread().getName()+" product a good");
viewGoods();
}
}
public void viewGoods() {
System.out.println("now "+count+" goods");
}
public int getCount() {
return count;
}
}
Main.java
package com.example;
public class Main {
public static void main(String[] args) {
Depository depository = new Depository();
Customer customer = new Customer();
customer.setDepository(depository);
Producter producter = new Producter();
producter.setDepository(depository);
Thread customer_1 = new Thread(customer);
customer_1.setName("customer_1");
customer_1.start();
Thread customer_2 = new Thread(customer);
customer_2.setName("customer_2");
customer_2.start();
Thread producter_ = new Thread(producter);
producter_.setName("producter_");
producter_.start();
}
}
有几个点要说一下:
1.main没有中止,当然无伤大雅
2.如果线程实现都是用Runable接口,所有线程用的锁都是Runnable实现类的(与本例无关,本例使用Despository)
3.写打印输出的时候碰到的问题,还是要把所有日志写在同步代码块里,虽然对真实结果无影响,但会显示乱了。
4.把增加货物与减少货物写在了仓库类里,不是太好,之后会想一下写进各自的类
5.关于notifyAll,当需要调用的时候,阻塞的类一定是不同类(比如,当从0->1时,生产者(实际是Despository)notify的都是正在阻塞的消费者)
6.之前写的sleep是在生产者消费者循环里,输出比较好,比较符合实际放货物拿货物的情况,争夺锁的情况比较少;而本例中放在同步代码块中,是为了更明显的看到synchronized的作用。
7.更改生产者或消费者数量时,要注意调sleep时间,否则count很可能涨不起来。
以下输出,有一个问题是,每当同步方法执行完释放锁, 相比于上面6,为什么有那么多该线程仍旧抢到锁的情况?
输出:
It's empty!
It's empty!
producter_ product a good
now 1 goods
producter_ product a good
now 2 goods
producter_ product a good
now 3 goods
producter_ product a good
now 4 goods
producter_ product a good
now 5 goods
producter_ product a good
now 6 goods
producter_ product a good
now 7 goods
producter_ product a good
now 8 goods
producter_ product a good
now 9 goods
producter_ product a good
now 10 goods
producter_ product a good
now 11 goods
producter_ product a good
now 12 goods
producter_ product a good
now 13 goods
producter_ product a good
now 14 goods
producter_ product a good
now 15 goods
producter_ product a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_2 take a good
now 18 goods
customer_2 take a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_1 take a good
now 18 goods
customer_1 take a good
now 17 goods
customer_1 take a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_2 take a good
now 19 goods
customer_2 take a good
now 18 goods
customer_2 take a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_1 take a good
now 18 goods
customer_1 take a good
now 17 goods
customer_1 take a good
now 16 goods
customer_1 take a good
now 15 goods
customer_1 take a good
now 14 goods
customer_1 take a good
now 13 goods
customer_1 take a good
now 12 goods
customer_1 take a good
now 11 goods
customer_1 take a good
now 10 goods
producter_ product a good
now 11 goods
producter_ product a good
now 12 goods
producter_ product a good
now 13 goods
producter_ product a good
now 14 goods
producter_ product a good
now 15 goods
producter_ product a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goodsIt's full!
更新:synchronized并不能保证所有线程平等抢同步代码块的执行权