直接上代码了,解释看注释即可:
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类饥渴,在其中加上标志位,并且通过判断标志位完成等待和唤醒的操作 */
}
}