山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(十七)- JUC(3)

目录

synchronized

面向对象改进

synchronized加在方法上

线程八锁


synchronized

线程1上锁之后,线程2无法获取锁不能够执行临时区,线程2阻塞等待线程1完成释放锁之后才能够使用。可以把synchronize类比成一个房间,每次有锁的人才能够进入房间做事情,就算cpu时间片用完,只要没有这个锁那么其他线程是无法进入房间的。当用完之后就会释放锁,并且唤醒那些阻塞的线程

解决

  
  @Slf4j
  public class Test {
  ​
      static int counter = 0 ;
  ​
      // 定义锁对象
      static Object lock = new Object();
  ​
      public static void main(String[] args) throws InterruptedException {
          Thread t1 = new Thread(() ->{
              for (int i = 0; i < 5000; i++) {
                  synchronized (lock){       // 上锁
                      counter ++ ;
                  }
              }
          });
  ​
          Thread t2= new Thread(() ->{
              for (int i = 0; i < 5000; i++) {
                  synchronized (lock){
                      counter -- ;
                  }
              }
          });
  ​
  ​
          t1.start();
          t2.start();
          t1.join();
          t2.join();
          System.out.println(counter);
  ​
      }
  ​
  }

synchonized实际上是使用对象锁保证了临界区内代码的原子性,临界区是不可分割的,不会被线程切换打断

面向对象改进

  
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Room room = new Room();
  ​
          Thread t1 = new Thread(() ->{
              for (int i = 0; i < 5000; i++) {
                  room.increment();
              }
          });
  ​
          Thread t2= new Thread(() ->{
              for (int i = 0; i < 5000; i++) {
                  room.decrement();
              }
          });
  ​
  ​
          t1.start();
          t2.start();
          t1.join();
          t2.join();
          System.out.println(room.getCounter());
  ​
      }
  ​
  }
  ​
  ​
  class Room{
      int count = 0 ;
  ​
      public void increment(){
          synchronized (this){
              count ++ ;
          }
      }
  ​
      public void decrement(){
          synchronized (this){
              count --;
          }
      }
  ​
      public int getCounter(){
          synchronized (this){
              return count;
          }
      }
    
  }

synchronized加在方法上

  
  class c1{
      public synchronized void test(){
          
      } 
  }
  ​
  class c1{
      public void test(){
          synchronized (this){
  ​
          }
      }
  }
  ​
  二者等价,锁住的是this对象

加载静态方法上相当于锁住类对象

线程八锁

情况1 : 1 2或者2 1

  
  ​
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
          new Thread(() -> {
              log.debug("begin");
              n1.b();
          }).start();
          
      }
  ​
  }
  ​
  ​
  @Slf4j
  class Number{
      public synchronized void a(){
          log.debug("1");
      }
  ​
      public synchronized void b(){
          log.debug("2");
      }
      
  ​
  }

情况2 : 1s后1 2 或 1s后2 1

  
  ​
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
          new Thread(() -> {
              log.debug("begin");
              n1.b();
          }).start();
  ​
      }
  ​
  }
  ​
  @Slf4j
  class Number{
      public synchronized void a() throws InterruptedException {
          Thread.sleep(1000);
          log.debug("1");
      }
  ​
      public synchronized void b(){
          log.debug("2");
      }
  ​
  ​
  }

情况3 : 3 ,1s后 1 2 || 3 , 2 1s后打印1 || 2 , 3 1s后打印1

  
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
          
          new Thread(() -> {
              log.debug("begin");
              n1.b();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n1.c();
          }).start();
  ​
      }
  ​
  }
  ​
  @Slf4j
  class Number{
      public synchronized void a()  {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public synchronized void b(){
          log.debug("2");
      }
  ​
      public  void c(){
          log.debug("3");
      }
  ​
  ​
  }

情况4 : 先2,1s后打印1

  
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          Number n2 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n2.b();
          }).start();
  ​
  ​
  ​
      }
  ​
  }
  @Slf4j
  class Number{
      public synchronized void a()  {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public synchronized void b(){
          log.debug("2");
      }
  ​
  ​
  }

情况5 : 先2,1s后打印1

  
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n1.b();
          }).start();
      }
  ​
  }
  ​
  @Slf4j
  class Number{
      public static synchronized void a()  {     // 锁住的是类对象
          try { 
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public synchronized void b(){
          log.debug("2");
      }
  ​
  ​
  }
  ​
  ​

情况6 : 1s后打印1 后2 || 2 1s后打印1

  
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n1.b();
          }).start();
  ​
      }
  ​
  }
  ​
  @Slf4j
  class Number{
      public static synchronized void a()  {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public static synchronized void b(){
          log.debug("2");
      }
  ​
  }

情况7 : 先2 1s后打印1

  
  import lombok.extern.slf4j.Slf4j;
  ​
  ​
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          Number n2 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n2.b();
          }).start();
  ​
  ​
  ​
      }
  ​
  }
  ​
  ​
  @Slf4j
  class Number{
      public static synchronized void a()  {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public  synchronized void b(){
          log.debug("2");
      }
  ​
  ​
  }
  ​
  ​

情况8 : 1s后打印1 后2 || 2 1s后打印1

  
  import lombok.extern.slf4j.Slf4j;
  ​
  ​
  @Slf4j
  public class Test {
      public static void main(String[] args) throws InterruptedException {
          Number n1 = new Number();
          Number n2 = new Number();
          new Thread(() -> {
              log.debug("begin");
              n1.a();
          }).start();
  ​
          new Thread(() -> {
              log.debug("begin");
              n2.b();
          }).start();
  ​
      }
  ​
  }
  ​
  @Slf4j
  class Number{
      public static synchronized void a()  {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new RuntimeException(e);
          }
          log.debug("1");
      }
  ​
      public static synchronized void b(){
          log.debug("2");
      }
  ​
  }

最近更新

  1. TCP协议是安全的吗?

    2024-05-25 18:45:20       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-25 18:45:20       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-25 18:45:20       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-25 18:45:20       18 阅读

热门阅读

  1. 小阿轩yx-Shell 编程规范与变量

    2024-05-25 18:45:20       10 阅读
  2. 设计模式-策略模式-使用

    2024-05-25 18:45:20       11 阅读
  3. 【Python爬虫】案例_斗鱼

    2024-05-25 18:45:20       12 阅读
  4. 【Linux+Docker】修改Docker容器中的hosts文件

    2024-05-25 18:45:20       10 阅读
  5. GPT-3:自然语言处理的预训练模型

    2024-05-25 18:45:20       9 阅读
  6. 语言模型的发展

    2024-05-25 18:45:20       10 阅读
  7. Android实现二维码扫描自定义扫描界面

    2024-05-25 18:45:20       7 阅读