直接上代码了,解释看注释即可:
package Thread; /* * 参考文章:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html * */ class thread8 implements Runnable { private int count= 2; public void run() { for(int i=0;i<10;++i) { sale(); } } public synchronized void sale() //对于方法进行同步 { if(count>0) { try { Thread.sleep(2000); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" index:"+ count--); } } } /* 人物信息类 */ class Info { public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public synchronized void set(String name, int age){ //在这里对于添加信息进行一体化同步处理 if(!flag) //flag == true代表现在可以set() { try { /*查看p1和p2出现的时间间隔和位置我们可以知道,wait()相当于将线程进行了堵塞,转而执行另一个线程,类似于断点,等另一个线程运行完以后,再继续运行下面的部分 *用专业的话说,就是调用wait()方法,则该线程失去锁,另一线程获取锁,执行完再释放锁,再由该线程捕获,继续下面的操作 * */ System.out.println("p1"); super.wait(); System.out.println("p2"); } catch (Exception e) { e.printStackTrace(); } } this.name=name; try { Thread.sleep(1000); }catch (Exception e) { e.printStackTrace(); } this.age=age; flag=false; super.notify(); /* 唤醒等待中的进程 */ } public synchronized void get() throws InterruptedException { if(flag) //说明现在应该是set()操作 { try{ super.wait(); }catch (Exception e) { e.printStackTrace(); } } try{ Thread.sleep(1000); }catch (Exception e) { e.printStackTrace(); } System.out.println(this.getName()+"<===>"+this.getAge()); flag=true; super.notify(); } private String name = "Rollen"; private int age = 20; private boolean flag=false; //标志位进行进程的唤醒和等待,flag == false 表示现在可以消费数据 } /** * 生产者 * */ class Producer implements Runnable{ private Info info=null; Producer(Info info) { this.info=info; } public void run(){ boolean flag=false; for(int i=0;i<6;++i) { if(flag) { this.info.set("Rollen", 20); flag=false; } else { this.info.set("ChunGe", 100); flag=true; } } } } /** * 消费者类 * */ class Consumer implements Runnable{ private Info info=null; public Consumer(Info info) { this.info=info; } public void run(){ for(int i=0;i<6;++i) { try { this.info.get(); } catch (InterruptedException e) { e.printStackTrace(); } } } } /* * 消费者 */ public class SychronizedThread { public static void main(String[] args) { thread8 trd8=new thread8(); Thread h1=new Thread(trd8); Thread h2=new Thread(trd8); Thread h3=new Thread(trd8); h1.start(); h2.start(); h3.start(); /* 生产者、消费者 */ Info info=new Info(); Producer pro=new Producer(info); Consumer con=new Consumer(info); new Thread(pro).start(); new Thread(con).start(); /* 现在我们对于Info类进行了封装 set() 和 get() ,但是仍然会出现重复读,覆盖之类的问题(即费按照 set() get() 交替的顺序出现) */ /* 为了解决上面出现的问题,我们就需要对于进程进行等待和唤醒 我们只需要修改Info类饥渴,在其中加上标志位,并且通过判断标志位完成等待和唤醒的操作 */ } }