java多线程的等待唤醒机制及如何解决同步过程中的安全问题

简介:

/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){ 
                 this.sex=sex;
                 this.name=name;  
   }
}
class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           if(x==1){
              p.setPerson("hjz", "man");
           }
           else p.setPerson("哈哈哈", "女女女女");
           x=(x+1)%2;
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           System.out.println(p.name + "....." + p.sex);
       }
   }
}
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}
*/
 
/*
输出的结果:
哈哈哈.....man
hjz.....man
hjz.....man
哈哈哈.....man
hjz.....女女女女
*/
 
//线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){ 
                 this.sex=sex;
                 this.name=name;  
   }
}
 
class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
          synchronized(new Object()){
               if(x==1){
                  p.setPerson("hjz", "man");
               }
               else p.setPerson("哈哈哈", "女女女女");
               x=(x+1)%2;
          }
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           System.out.println(p.name + "....." + p.sex);
       }
   }
}
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}
 */
 
//同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
//本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
/*   class Input implements Runnable{
   int x=0;
   Person p;
    
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
          synchronized(p){
               if(p.flag){
                 try{
                     p.wait();
                   }catch(InterruptedException e){
                   }
               }
               if(!p.flag){
                   if(x==1){
                      p.setPerson("hjz", "man");
                   }
                   else p.setPerson("哈哈哈", "女女女女");
                   x=(x+1)%2;
               }
                
               p.flag=true;
               p.notify();
                
          }
       }
   }
} */
 
 
//现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
//调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){
       synchronized(this){
         if(!flag){
             try{
                wait();
             }catch(InterruptedException e){}
         }
         if(flag){
                 this.sex=sex;
                 try{
                    Thread.sleep(100);
                 }catch(InterruptedException e){}
                 this.name=name;
         }
         flag=false;
         notify();
       }
   }
    
   public void outPerson(){
      synchronized(this){
          if(flag){
             try{
                 wait();
             }catch(InterruptedException e){}
          }
          if(!flag){
              System.out.println(name + "....." + sex);
          }
          flag=true;
          notify();
      }
   }
}
 
class Input implements Runnable{
   int x=0;
   Person p;
    
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
                   if(x==1){
                      p.setPerson("hjz", "man");
                   }
                   else p.setPerson("哈哈哈", "女女女女");
                   x=(x+1)%2;
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           p.outPerson();
       }
   }
} 
 
 
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}

目录
相关文章
|
9月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
383 0
|
Java 数据库
【YashanDB知识库】kettle同步大表提示java内存溢出
在数据导入导出场景中,使用Kettle进行大表数据同步时出现“ERROR:could not create the java virtual machine!”问题,原因为Java内存溢出。解决方法包括:1) 编辑Spoon.bat增大JVM堆内存至2GB;2) 优化Kettle转换流程,如调整批量大小、精简步骤;3) 合理设置并行线程数(PARALLELISM参数)。此问题影响所有版本,需根据实际需求调整相关参数以避免内存不足。
|
安全 Java 开发者
Java并发迷宫:同步的魔法与死锁的诅咒
在Java并发编程中,合理使用同步机制可以确保线程安全,避免数据不一致的问题。然而,必须警惕死锁的出现,采取适当的预防措施。通过理解同步的原理和死锁的成因,并应用有效的设计和编码实践,可以构建出高效、健壮的多线程应用程序。
255 21
|
Java Shell 数据库
【YashanDB 知识库】kettle 同步大表提示 java 内存溢出
【问题分类】数据导入导出 【关键字】数据同步,kettle,数据迁移,java 内存溢出 【问题描述】kettle 同步大表提示 ERROR:could not create the java virtual machine! 【问题原因分析】java 内存溢出 【解决/规避方法】 ①增加 JVM 的堆内存大小。编辑 Spoon.bat,增加堆大小到 2GB,如: if "%PENTAHO_DI_JAVA_OPTIONS%"=="" set PENTAHO_DI_JAVA_OPTIONS="-Xms512m" "-Xmx512m" "-XX:MaxPermSize=256m" "-
|
人工智能 监控 安全
Java智慧工地(源码):数字化管理提升施工安全与质量
随着科技的发展,智慧工地已成为建筑行业转型升级的重要手段。依托智能感知设备和云物互联技术,智慧工地为工程管理带来了革命性的变革,实现了项目管理的简单化、远程化和智能化。
359 5
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
Java 调度
【JavaEE】——线程的安全问题和解决方式
【JavaEE】——线程的安全问题和解决方式。为什么多线程运行会有安全问题,解决线程安全问题的思路,synchronized关键字的运用,加锁机制,“锁竞争”,几个变式
|
SQL 安全 Java
Java 异常处理:筑牢程序稳定性的 “安全网”
本文深入探讨Java异常处理,涵盖异常的基础分类、处理机制及最佳实践。从`Error`与`Exception`的区分,到`try-catch-finally`和`throws`的运用,再到自定义异常的设计,全面解析如何有效管理程序中的异常情况,提升代码的健壮性和可维护性。通过实例代码,帮助开发者掌握异常处理技巧,确保程序稳定运行。
406 2
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
231 4
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
下一篇
开通oss服务