JAVA线程的notify和wait

线程的notify:

1)要在synchronized代码块或方法里使用

2)唤醒在同一个监视器(synchronized)上的等待线程,如果不止一个线程在此同步监视器等待,则根据调度对策选择唤醒其中一个。只有当前线程放弃对当前同步监视器的锁定后才能执行被唤醒的线程。

线程的wait:

1)要在synchronized代码块或者方法里使用

2)导致当前线程等待,直到其他线程调用该同步监视器的notify()或者notifyAll()方法。

3)wait有三种方法重载。

身为一个小白,最近在学习线程,使用的教材书是《疯狂JAVA讲义》,在做书上课后习题时对wait和notify函数的使用有了进一步,特意写下笔记,小小拙见,如果有什么不对欢迎补充。

首先,需要了解synchronized,一个线程执行同步代码块时,首先要得到对同步监视器的锁定。

整个流程就是“锁定-执行-解锁(释放锁)”

书上的简单问题

一个错误例子:

public class Test_1
{
   public static void main(String args[ ])
   {
       WriteWordThread  zhang,wang;

       zhang=new WriteWordThread("张小红");        //新建线程。
       wang=new WriteWordThread("JamsKeven");     //新建线程。
       zhang.start();                             //启动线程。
       wang.start();                              //启动线程
       for(int i=1;i<=8;i++)
       {
         System.out.println("我是主线程中的语句"+Thread.currentThread().getName());
       }
       System.out.println("done");
   }
}
class  WriteWordThread extends Thread
{
  
   tt test;
   
   WriteWordThread()
   {
     test = new tt(); 
   }
    WriteWordThread(String s)
   {
       setName(s);             //调用Thread类的方法setName为线程起个名字。
   }
   public synchronized void run()
   { 
    //System.out.println(Thread.currentThread().getName());
    //test.ttt(Thread.currentThread().getName());
     int n = 0;
      if(Thread.currentThread().getName().equals("张小红")){
        try{
          for(int i = 1; i <= 52; ++i){
              System.out.print(i);
              ++n;
           
              if(n%2==0){
                notify();
                wait();
              } 
              
        }
      }catch(Exception e){System.out.println("1  "+e.toString());}
      }
      else{
              try{
                Thread.sleep(10);//为了让数字先打印
                for(char i = 'A'; (int)i <= (int)'Z'; ++i){
                System.out.print(i);
                if((int)i < (int)'Z')
                {
                  notify();
                  wait(); 
                }
              }
              notify();//字母打印完后,唤醒等待的数字线程
            }catch(InterruptedException e){System.out.println(e.toString());}
      }
   }
}

这个错误的例子犯的错误就是不是同一个监视器,所以两个线程执行一次后就一直处于等待中,没有线程唤醒它。

正确的例子(也有更加简单的写法)

public class Test_1
{
   public static void main(String args[ ])
   {
       WriteWordThread  all =new WriteWordThread();
       //WriteWordThread  zhang,wang;
       Thread zhang=new Thread(all);        //新建线程。
       Thread wang=new Thread(all);     //新建线程。
       zhang.setName("张小红");
       wang.setName("JamsKeven");
       //zhang=new WriteWordThread("张小红");        //新建线程。
       //wang=new WriteWordThread("JamsKeven");     //新建线程。
       zhang.start();                             //启动线程。
       wang.start();                              //启动线程
       for(int i=1;i<=8;i++)
       {
         System.out.println("我是主线程中的语句"+Thread.currentThread().getName());
       }
       System.out.println("done");
   }
}
class  WriteWordThread extends Thread
{
  
   
   WriteWordThread()
   {
   }
    WriteWordThread(String s)
   {
       setName(s);             //调用Thread类的方法setName为线程起个名字。
   }
   public void set(String s){
    setName(s); 
   }
   public synchronized void run()
   { 

     int n = 0;
      if(Thread.currentThread().getName().equals("张小红")){
        try{
          for(int i = 1; i <= 52; ++i){
              System.out.print(i);
              ++n;
              if(n%2==0){
                notify();
                wait();
              } 
              
        }
      }catch(Exception e){System.out.println("1  "+e.toString());}
      }
      else{
              try{
                Thread.sleep(10);
                for(char i = 'A'; (int)i <= (int)'Z'; ++i){
                System.out.print(i);
                if((int)i < (int)'Z')
                {
                  notify();
                  wait(); 
                }
              }
              notify();
            }catch(InterruptedException e){System.out.println(e.toString());}
      }
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值