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();
    }
}

目录
相关文章
|
1月前
|
Java 云计算
Java多线程编程中的同步与互斥机制探析
在当今软件开发领域,多线程编程是一项至关重要的技能。本文将深入探讨Java中的同步与互斥机制,分析其在多线程环境下的应用及实现原理,帮助读者更好地理解并运用这一关键技术。
23 4
|
29天前
|
开发框架 Java API
java反射机制的原理与简单使用
java反射机制的原理与简单使用
17 1
|
1月前
|
资源调度 算法 Linux
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
64 0
|
6天前
|
存储 安全 Java
Java中的容器,线程安全和线程不安全
Java中的容器,线程安全和线程不安全
13 1
|
6天前
|
存储 缓存 安全
Java并发基础之互斥同步、非阻塞同步、指令重排与volatile
在Java中,多线程编程常常涉及到共享数据的访问,这时候就需要考虑线程安全问题。Java提供了多种机制来实现线程安全,其中包括互斥同步(Mutex Synchronization)、非阻塞同步(Non-blocking Synchronization)、以及volatile关键字等。 互斥同步(Mutex Synchronization) 互斥同步是一种基本的同步手段,它要求在任何时刻,只有一个线程可以执行某个方法或某个代码块,其他线程必须等待。Java中的synchronized关键字就是实现互斥同步的常用手段。当一个线程进入一个synchronized方法或代码块时,它需要先获得锁,如果
22 0
|
7天前
|
监控 Java 关系型数据库
JVM工作原理与实战(十三):打破双亲委派机制-线程上下文类加载器
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了打破双亲委派机制的方法、线程上下文类加载器等内容。
|
17天前
|
安全 Java 调度
深入理解Java中的线程安全与锁机制
【4月更文挑战第6天】 在并发编程领域,Java语言提供了强大的线程支持和同步机制来确保多线程环境下的数据一致性和线程安全性。本文将深入探讨Java中线程安全的概念、常见的线程安全问题以及如何使用不同的锁机制来解决这些问题。我们将从基本的synchronized关键字开始,到显式锁(如ReentrantLock),再到读写锁(ReadWriteLock)的讨论,并结合实例代码来展示它们在实际开发中的应用。通过本文,读者不仅能够理解线程安全的重要性,还能掌握如何有效地在Java中应用各种锁机制以保障程序的稳定运行。
|
22天前
|
Java 程序员 开发者
深入理解Java异常处理机制
在Java编程中,异常处理是确保程序健壮性与稳定性的重要组成部分。本文旨在深度剖析Java异常处理机制的核心概念、结构及其实际应用策略,帮助开发者更好地理解并运用异常处理来优化程序设计。我们将从Java异常体系结构入手,探讨try-catch-finally语句块的执行流程,分析自定义异常的必要性与实现方式,并通过实例演示如何有效地管理和处理异常情况。
23 3
|
29天前
|
存储 编解码 算法
【ffmpeg音视频同步】解决ffmpeg音视频中多线程之间的数据同步问题
【ffmpeg音视频同步】解决ffmpeg音视频中多线程之间的数据同步问题
38 2
|
29天前
|
设计模式 XML 存储
java中的反射机制
java中的反射机制
12 1

热门文章

最新文章