Java多线程(下)

等待唤醒机制

等待唤醒机制同样是为了解决多线程安全性问题。比如,解决消费数目多余生产数目。

1.        wait(), notify(), notifyAll()

都出现在同步中,因为要对持有监视器(锁)的线程操作,而只有同步中才有锁。

2.        被等待(wait())线程,被同一个锁上的notify()唤醒。

3.        锁可以是任意对象,可以被任意对象(锁)调用的方法定义在Object类中

4.        程序示例:

classPersonalInfo//资源

{

         private String name;

         private String sex;

         private boolean flag = false;//资源空间需要标记,生产者消费者的例子

         public synchronized void setInfo(Stringname, String sex)//同步函数

         {

                   if(this.flag)

                   {

                            try{ this.wait();}//等待

                            catch(Exception e){}

                   }

                   this.name = name;

                   this.sex = sex;

                   this.flag = true;

                   this.notify();

         }

         public synchronized void getInfo()

         {

                   if(!this.flag)

                   {

                            try{ this.wait();}//唤醒

                            catch(Exception e){}

                   }

                   System.out.println(name+"---------"+sex);

                   this.flag = false;

                   this.notify();

         }

}

classInPut implements Runnable//创建输入继承的类

{

         private PersonalInfo pf;

         InPut(PersonalInfo pf)

         {

                   this.pf = pf;

         }

         public void run()

         {

                   int order = 0;

                   while(true)

                   {

                            if(0 == order)

                            {

                                     pf.setInfo("ff","man");

                            }

                            else

                            {

                                     pf.setInfo("hh","woman");

                            }

                            order = (order +1)%2;

                   }

         }

}

classOutPut implements Runnable//创建输出线程的类

{

         private PersonalInfo pf;

         OutPut(PersonalInfo pf)

         {

                   this.pf = pf;

         }

         public void run()

         {

                   while(true)

                   {

                            pf.getInfo();

                   }

         }

}

publicclass WaitNotify

{

         public static void main(String[] args)

         {

                   PersonalInfo pf = newPersonalInfo();

                   new Thread(newInPut(pf)).start();

                   new Thread(newOutPut(pf)).start();

         }

}

其中,wait()与sleep()的区别是:前者释放cpu执行权,释放锁;后者释放cpu执行权,不释放锁。

5.        当生产者跟消费者都不止一个时,我们可以采用notifyAll()

classGoods

{

         private String name;

         private int num = 200;

         private boolean flag = false;

         public synchronized void setInfo(Stringname)

         {

                   if(0 < this.num)

                   {

                            while(flag)

                            {

                                     try{this.wait(); }

                                     catch(Exceptione){}

                            }

                            this.name =name+"----"+num--;

                            System.out.println(Thread.currentThread().getName()+ "----生产者----" + this.name);

                            this.flag = true;

                            this.notifyAll();//线程池中的线程全部唤醒。

                   }

         }

         public synchronized void getInfo()

         {

                   while(!flag)//此处需要用到while,循环判断

                   {

                            try{ this.wait(); }

                            catch(Exception e){}

                   }

                   System.out.println(Thread.currentThread().getName()+ "----消费者----" + this.name);

                   this.flag = false;

                   this.notifyAll();//全部唤醒!主要是唤醒对面,以防进程全部进入wait状态

         }

}

classProducer implements Runnable//创建生产者线程

{

         private Goods apple;

 

         Producer(Goods fruit)//有什么用啊?

         {

                   apple = fruit;

         }

         public void run()

         {

                   while(true)

                            apple.setInfo("苹果");

         }

}

classConsumer implements Runnable

{

         private Goods apple;

         Consumer(Goods fruit)

         {

                   apple = fruit;

         }

         public void run()

         {

                   while(true)

                   {

                            apple.getInfo();

                   }

         }

}

classProducerConsumer

{

         public static void main(String[] args)

         {

                   Goods fushi = new Goods();

                   Producer p1 = newProducer(fushi);

                   Producer p2 = new Producer(fushi);

                   Consumer c1 = newConsumer(fushi);

                   Consumer c2 = newConsumer(fushi);

                   Thread tp1 = new Thread(p1,"famer1");

                   Thread tp2 = new Thread(p2,"famer2");

                   Thread tc1 = new Thread(c1,"buyer1");

                   Thread tc2 = new Thread(c2,"buyer2");

                   tp1.start();

                   tp2.start();

                   tc1.start();

                   tc2.start();

         }

}

 

上面程序,在JDK5.0中提供了多线程升级解决方案:

1)        将同步synchronized替换成了显式Lock操作

2)        将Object中的wait,notify,notifyAll替换成了Condition对象的await,signal

该对象可以通过Lock锁进行获取

3)        它实现本方置唤醒对方的操作

importjava.util.concurrent.locks.*;//导入包

classGoods

{

         private String name;

         private int num = 200;

         private boolean flag = false;

         private Lock lock = newReentrantLock();

         private Condition condition_pro =lock.newCondition();

         private Condition condition_con =lock.newCondition();

        

         public void setInfo(String name) throwsInterruptedException//因为没写catch

         {

                   lock.lock();

                   try

                   {

                            while(flag)

                            {

                                     condition_pro.await();

                            }

                            this.name =name+"----"+num--;

                            System.out.println(Thread.currentThread().getName()+ "----生产者----" + this.name);

                            this.flag = true;

                            condition_con.signal();

                   }

                   finally

                   {

                            lock.unlock();

                   }

         }

         public void getInfo()throwsInterruptedException

         {

                   try

                   {

                            while(!flag)//此处需要用到while,循环判断

                            {

                                     condition_con.await();

                            }

                            System.out.println(Thread.currentThread().getName()+ "----消费者----" + this.name);

                            this.flag = false;

                            condition_pro.signal();

                   }

                   finally

                   {

                            lock.unlock();

                   }

         }

}

classProducer implements Runnable//创建线程

{

         private Goods apple;

         Producer(Goods apple_ipad)//有什么用啊?

         {

                   apple = apple_ipad;

         }

         public void run()

         {

                   while(true)

                   {

                            try

                            {

                                     apple.setInfo("苹果");

                            }

                            catch(InterruptedException e)

                            {

                            }

                   }

         }

}

classConsumer implements Runnable

{

         private Goods apple;

         Consumer(Goods apple_ipad)

         {

                   apple = apple_ipad;

         }

         public void run()

         {

                   while(true)

                   {

                            try

                            {

                                     apple.getInfo();

                            }

                            catch(InterruptedException e)

                            {

                            }

                   }

         }

}

classProducerConsumer2

{

         public static void main(String[] args)

         {

                   Goods ipad4 = new Goods();

                   Producer p = newProducer(ipad4);

                   Consumer c = newConsumer(ipad4);

                   Thread tp1 = new Thread( p,"factory1");

                   Thread tp2 = new Thread( p,"factory2");

                   Thread tc1 = new Thread(c,"buyer1");

                   Thread tc2 = new Thread(c, "buyer2");

                   tp1.start();

                   tp2.start();

                   tc1.start();

                   tc2.start();

         }

}

停止线程

开启多线程运行,运行代码通常是循环结构。因此,只要控制住循环,也就是让线程结束。

class StopThread implements Runnable

{

         privateboolean flag = true;

 

         publicvoid run()

         {

                   while(flag)

                   {

                            System.out.println(Thread.currentThread().getName()+".....run");

                   }

         }

        

         publicvoid changeFlag()//改变标记的方法

         {

                   flag= false;

         }

}

 

public class StopThreadTest

{

         publicstatic void main(String[] args)

         {

                   StopThreadst = new StopThread();

 

                   Threadt1 = new Thread(st);

                   Threadt2 = new Thread(st);

 

                   t1.start();

                   t2.start();

 

                   intnum = 0;//静态中不能私有化

                   while(true){

                            if(60< num++)

                            {

                                     st.changeFlag();

                                     break;

                            }

                            System.out.println(Thread.currentThread().getName()+"....."+num);

                   }

         }

}

特殊情况:(同步时)当线程处于了冻结状态,就不会读取到标记,线程也就不会结束。

当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结进行清除。强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。

Thread类提供了该方法interrupt()

class StopThread implements Runnable

{

         privateboolean flag = true;

 

         publicsynchronized void run()

         {

                   while(flag)

                   {

                            try

                            {

                                     wait();

                            }

                            catch(InterruptedException e)

                            {

                                     System.out.println(Thread.currentThread().getName()+".....Exception");

                                     flag= false;      //在异常处理中改变标记

                            }

                            System.out.println(Thread.currentThread().getName()+".....run");

                   }

         }

}

 

public class StopThreadTest2

{

         publicstatic void main(String[] args)

         {

                   StopThreadst = new StopThread();

 

                   Threadt1 = new Thread(st);

                   Threadt2 = new Thread(st);

 

                   t1.start();

                   t2.start();

 

                   intnum = 0;//静态中不能私有化

                   while(true){

                            if(60< num++)

                            {

                                     t1.interrupt();//中断,强制清除冻结状态

                                     t2.interrupt();

                                     break;

                            }

                            System.out.println(Thread.currentThread().getName()+"....."+num);

                   }

                   System.out.println("gameover");

         }

}

join

当A线程执行到了B线程的join()方法时,A就会等待,等B线程都执行完,A才会执行

join可以用来临时加入线程执行

class ForJoin implements Runnable

{

         publicvoid run()

         {

                   for(intx = 0; x < 70; x++)

                   {

                            System.out.println(Thread.currentThread().getName()+"...."+x);

                   }

         }

}

 

public class JoinTest

{

         publicstatic void main(String[] args) throws Exception

         {

                   ForJoinjoin = new ForJoin();

 

                   Threadt1 = new Thread(join);

                   Threadt2 = new Thread(join);

 

                   t1.start();

 

                   t1.join();

 

                   t2.start();

 

                   for(intx = 0; x < 80; x++)

                   {

                            System.out.println(Thread.currentThread().getName()+"......"+x);

                   }

                   System.out.println("over");

         }

}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值