多线程wait,notify,synchronzied以及lock ,await,signal的用法

  今天翻开以前的笔记练了下基本多的多线程。synchronzied,notify,wait的用法,主要用flg下标去控制wait


package classForm;


public class ThreadDemo4 {
 public static void main(String[] args) {
  Res1 res1 = new Res1();
  InpThread inpThread = new InpThread(res1);
  inpThread.start();
  OutThread outThread = new OutThread(res1);
  outThread.start();
 }
}

class Res1{
 public String name;
 public String sex;
 public boolean flg=false;//flag为false戏按成未读取值xian
}

//写入线程
class InpThread extends Thread{
 public Res1 res1;
 public InpThread(Res1 res1){
  this.res1 = res1;
 }
 @Override
 public void run() {
  int count = 0;
  while(true){
   synchronized (res1) {
     if(res1.flg){
      try {
       res1.wait();
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
     if(count == 0){
      res1.name="小明";
      res1.sex="男";
     }else{
      res1.name="小红";
      res1.sex="女";
     }
     count=(count+1)%2;
     //和wait一起使用,唤醒另外一个线程
     res1.flg=true;
     res1.notify();
    }
     
  }
 }
}
//读的线程
class OutThread extends Thread{
 public Res1 res1;
 public OutThread(Res1 res1){
  this.res1 = res1;
 }
 @Override
 public void run() {
  while(true){
   synchronized (res1) {
     if(!res1.flg){
      try {
       res1.wait();
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
     //等待用flg去控制,其他代码块不能写到flg里面
     System.out.println(res1.name+"---"+res1.sex);
     res1.flg=false;
     res1.notify();
    }
  }
 }
}


其实synchronized和lock锁是比较类似的,下面请看lock锁的案例

package classForm;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo05 {
 public static void main(String[] args) {
  Res2 res2 = new Res2();
  InpThread01 inpThread = new InpThread01(res2);
  inpThread.start();
  OutThread01 outThread = new OutThread01(res2);
  outThread.start();
 }
}

class Res2 {
 public String name;
 public String sex;
 public boolean flg = false;// flag为false戏按成未读取值xian
 public Lock lock = new ReentrantLock();// 使用lock锁
 Condition condition = lock.newCondition();//
}

// 写入线程
class InpThread01 extends Thread {
 public Res2 res2;

 public InpThread01(Res2 res2) {
  this.res2 = res2;
 }

 @Override
 public void run() {
  int count = 0;
  while (true) {
   res2.lock.lock();//上锁
   if (res2.flg) {
    try {
     res2.condition.await();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   if (count == 0) {
    res2.name = "小明";
    res2.sex = "男";
   } else {
    res2.name = "小红";
    res2.sex = "女";
   }
   count = (count + 1) % 2;
   // 和wait一起使用,唤醒另外一个线程
   res2.flg = true;
   res2.condition.signal();
   res2.lock.unlock();//解锁
  }

 }
}

// 读的线程
class OutThread01 extends Thread {
 public Res2 res2;

 public OutThread01(Res2 res2) {
  this.res2 = res2;
 }

 @Override
 public void run() {
  while (true) {
   res2.lock.lock();
    if (!res2.flg) {
     try {
      res2.condition.await();//相当于wait
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
    // 等待用flg去控制,其他代码块不能写到flg里面
    System.out.println(res2.name + "---" + res2.sex);
    res2.flg = false;
    res2.condition.signal();//类似notify
    res2.lock.unlock();//解锁
   }
 }
}


综上所述,wait,notify,synchronzied要一起使用,并且上锁必须要同一对象,lock ,await,signal也是一组。他们的区别,前者相对操作简单,是自动上锁,自动解锁,后者是手动上锁解锁。

上一篇:[Bat]如何彻底关闭每个盘符默认的共享$(即使重启也有效)


下一篇:深度学习笔记(八)Focal Loss