多线程经典例题
需求:创建一个商品类, 商品有编号, 价格, 生产日期属性,商品的编号不能重复.创建一个仓库类, 用户储存商品, 仓库类中使用Map集合, 将商品的编号当作是key,仓库有存储和取出的方法,创建两个工人和两个消费者, 工人生产商品, 消费者消费商品, 永不停止如果消费者消费时没有商品了, 就打印一句话:"快点生产呀", 然后休息1秒钟。
- 仓库类实现代码
package mulithread;
import java.util.HashMap;
import java.util.Set;
public class CanKu {
//因为集合是worker和consumer公用部分。在程序运行时需要加锁保证数据安全。
public static HashMap<Integer,Goods> map=new HashMap<>();
//向仓库中添加商品
public synchronized static void add(Goods goods){
map.put(goods.getNum(), goods);
}
//从仓库中移除商品
public synchronized static Goods get(){
//获取商品集合中的所有key
Set<Integer> keyset=map.keySet();
//因为map集合是集合无序的所以获取一个无论先后顺序都是随机的
//所以kyset集合也是无序的只需用获取遍历第一个元素即可
Integer key=null;
for(Integer integer: keyset){
key=integer;
break;
}
//通过key移除map中对应的元素
if(key==null){
return null;
}else{
return map.remove(key);
}
}
}
- 工人类实现代码
package mulithread;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
public class Worker extends Thread{
private static int num=0;
public Worker(String name) {
// TODO Auto-generated constructor stub
super(name);
}
@Override
public void run (){
System.out.println("11111");
while(true){
int n=0;
//多条线程访问同一份数据时,只有公用的部分才会出现临界资源安全问题
synchronized(Class.class){
num++;
n=num;
}
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str =sdf.format(new Date());
Goods goods =new Goods(n, 25,str);
synchronized(Lock.class){
CanKu.add(goods);
System.out.println(getName()+":我生产了一件产品!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 消费者类实现代码
package mulithread;
import java.util.concurrent.locks.Lock;
public class Consumer extends Thread {
//这个构造方法主要是为了给线程起名字
public Consumer(String name){
super(name);
}
@Override
public void run(){
while(true){
Goods goods=null;
synchronized(Lock.class){
goods=CanKu.get();
}
if(goods==null){
System.out.println(getName()+"赶紧生产呀!");
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(getName()+"刚买到一个大宝贝"+goods);
}
}
}
}
- 货物类实现代码
package mulithread;
public class Goods {
private int num ;
private int price;
private String date;
public Goods() {
super();
// TODO Auto-generated constructor stub
}
public Goods(int num, int price, String date) {
super();
this.num = num;
this.price = price;
this.date = date;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@Override
public String toString() {
return "Goods [num=" + num + ", price=" + price + ", date=" + date + "]";
}
}
- 测试类实现代码
package mulithread;
public class TestObj {
public static void main(String[] args) {
Worker w1=new Worker("生产者线程1");
Worker w2=new Worker("生产者线程2");
Consumer c1=new Consumer("消费者线程1");
Consumer c2=new Consumer("消费者线程2");
w1.start();
w2.start();
c1.start();
c2.start();
}
}