java多线程的同步 通信以及生产消费者问题

简介: Demo1 /*   Runable接口比直接从Thread继承方便的多  。  *    new  Thread(...) ;这样即使我们传递了同一个实现了Runnable接口的多个对象那么 也是多个线程 ,而且多个线程共享数据域.

Demo1

/*   Runable接口比直接从Thread继承方便的多  。 
*    new  Thread(...) ;这样即使我们传递了同一个实现了Runnable接口的多个对象那么 也是多个线程 ,而且多个线程共享数据域.
*    否则new Thread 创建的多个线程之间 互不相干  ,数据之间互不干涉
*    同步就是为了实现 在多个线程同时对一个资源进行操作的时候 要一个一个的执行 ,
*    只有等占有CPU的 线程完事之后 其他等待线程才能进入就绪状态等待运行
*    java中可以用 synchrozined(Object obj){}      实现代码块的同步      参数是任意对象 
*    不但可以利用synchronized语句块  也可以在方法的前面 声明 synchronized      
*    同步原理是对象的标志位 初始为1  当进入代码块后 obj的标志位变为 0  这时候其他线程则不能 进入代码块执行 而进入等待状态
*    直到先进入的那个线程完事然后就会为这个线程解锁 。 其他线程才可能开始运行   火车票的售票系统就是一个多线程很好的运用的例子
*    同步是以程序的性能为代价的   ,同步方法是以类的this对象为同步对象的  而 synchronized块是以我们指定的对象为 同步对象
*    如果想让代码块和同步方法同步那么 使用的同步对象 必须都为this
*/  
public class  ThreadDemo2
{
   public static void main(String []args)
   {
       MyThread mt=new MyThread() ;  
       //mt.start() ;
       new Thread(mt) .start() ;
       try
      {
       Thread.sleep(10) ; //每当产生一个线程CPU不会立马去执行 ,这之间既有一个微小的时间间隔 。
      }
      catch(Exception e)
      {
       System.out.println(e.toString()) ;
      }
       mt.str="method";
       new Thread(mt) .start() ;
   }
}
class  MyThread    implements Runnable// extends   Thread
{  
   int tickets=100 ;
   String str=new String("");
   public void run()
   {
       if(str.equals("method"))
       {
        while(true)
        {
         running() ;
        }
       }
       else
       {
        while(true)
        {
         synchronized(str)
        {
         if(tickets>0 )
         {
          System.out.println("block:"+Thread.currentThread().getName()+"sells"+tickets--);
         }
        }
         
        }
       }
   }
   public  synchronized  void running()
   {    
      if(tickets>0) 
       {
        try{Thread.sleep(10);}catch(Exception ex){}
        System.out.print("method:") ;
        System.out.println(Thread.currentThread() +"sell " + tickets-- ) ;
       }
   }
}  

 

Demo2:

/*
*   java多线程中 有前台线程和后台线程,前台线程 是指 main所在的主线程 和其他 创建的线程 ,如果在线程调用start 之前调用  setDeamon(true)
*   那么 这个线程就是一个后台线程,在进程中如果没有一个前台线程 那么后台线程也随之退出,从而进程也退出 。如果没有调用setDeamon(true)或者
*   调用setDeamom(false)那么这个线程就是前台线程 ,只要一个进程中还存在前台线程 那么即使mian方法所在的线程退出了 ,那么这个前台子线程也会继续执行
*   直至退出  。
*   Tread类额join方法 是将一个线程合并到另一个线程中, 可以设置合并的时间间隔
*   我们实现自己的线程类有2中方法  :
*   1、直接从Thread继承而来  实现 run方法  。
*   2、实现Runnable接口,并且实现run方法 。 Thread  th=new Thread(....) ;//吧我们自己实现的类的对象作为参数传进去   .
*   join 方法可以将一个线程合并到另一个线程 中 而且还可以指定线程合并的时间间隔
*
*/
public  class  ThreadDemo1
{
      public static  void main(String[]args) 
      {
        //MyThread tt=new MyThread() ; tt.start() ;可以从 Thread类派生一个线程类
        Thread tt=new Thread(new MyThread()) ;  //可以通过Thread类的带参数的构造方法 传递一个实现了Runnable接口的对象
   //     tt.setDaemon(true) ;//将线程设置为 后台线程  主线层退出这个线程也会随着退出 
        tt.start() ;
        int index=0 ;
        while(true)
        {
         if(index++==100)
         try{
           tt.join(5000) ;
         }
         catch(Exception ex)
        {
         System.out.println(ex.toString()) ;
        }
          
         System.out.println("run:"+Thread.currentThread().getName()) ;
        }
      }

}
class  MyThread  implements Runnable//extends    Thread
{
    public void run()
    {
      while(true)
      {
      System.out.println("run:"+Thread.currentThread().getName()) ;
      }
    }
}

Demo3:

/*   线程之间的通信是协调线程同步的重要方法   、
*    Object类的 wait方法通告同步对象进入等待状态,直到其他线程得到同步对象 并且调用 notity方法 ,等待线程才会继续执行
*    notify方法 是通告同步对象的等待线程进入恢复运行 
*    notifyAll通告所有堵塞线程恢复运行
*     下面是一个生产消费者的问题   ,在对于类的操作的时候 一定要有面向对象的思想  。  否则 就会非常的杂乱
*/
class  Producer  implements  Runnable
{
 Q q  ;
 public Producer(Q q)
 {
  this.q=q ;
 }
 public  void run()
 { 
    int i=0 ;
    while(true)
    {
    /* synchronized(q)
     {
      if(q.bFull==true)
          try{q.wait() ;}catch(Exception ex){}
         if(i==0)
     {
       q.name="zhangsan" ;
       try{
       Thread.sleep(1) ;
      }catch(Exception ex){}
       q.sex="male"  ;
     }
     else
     {
      q.name="lisi"  ;
      q.sex="female" ;
     }  
     q.bFull=true ;
     q.notify() ;
    }
     i=(i+1)%2 ;
     */ 
   
     if(i==0 )
      q.push("zhangsan","male");
       else
      q.push("lisi","female") ;  
      i=(i+1)%2 ;
    }
      
 }
}
class Consumer implements  Runnable 
{  
   Q q ;
   public Consumer(Q q)
   {
    this.q=q ;
   }
   public   void  run()
   {
      while(true)
     {
     /*  synchronized(q)
       {
         if(!q.bFull)
         {
        try{q.wait() ;}catch(Exception ex){}
          }
          System.out.println(q.name+":"+q.sex) ;
          q.bFull=false ;
           q.notify() ;
        }
      */
      q.get() ;
     }
   }
}

class  Q   //以面向对象的思想对线程之间的通信进行封装从而实现消费者 生产社的问题
{
 String name="unknown"  ;
 String sex ="unknown"  ;
 boolean bFull=false ;
 public synchronized void push(String name,String sex)
 {     
      if(this.bFull==true)
               try{wait() ;}catch(Exception ex){}
       this.name=name ;
       this.sex=sex   ; 
       bFull=true ;
       try{notify() ;}catch(Exception ex){}
 }
 public synchronized void get()
 {
  if(this.bFull==false)
     try{wait() ;}catch(Exception ex){}
  System.out.println("name:"+this.name+" sex:"+this.sex) ;
     bFull=false ;
     try{notify() ;}catch(Exception ex){}
 }
}


class  ThreadTest  implements  Runnable    //这个线程类 来模拟线程的声明结束  因为Thread类的 stop suspend等方法都已经过时了
{                                          //所以有时候我们对于线程的开始和结束要自己设置标志位来
  boolean bRun=true ;
  int index=0 ;
  public  void  stopMe()
  {
   bRun=false ;
  }
  public  void run()
  {
   while(bRun)
   { 
      if(++index>100)
        stopMe() ;
     System.out.println(Thread.currentThread().getName()+" is running!");
   }
  
   }
 
}

public  class  ThreadDemo3
{
  
   public static void main(String[]args)
   {
    
   Q q=new Q() ;
    new Thread(new Producer(q)).start() ;
   new Thread(new Consumer(q)).start() ; 
 
   }
}

 

目录
相关文章
|
9月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
383 0
|
10月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
702 5
|
10月前
|
监控 搜索推荐 Java
Java 多线程最新实操技术与应用场景全解析:从基础到进阶
本文深入探讨了Java多线程的现代并发编程技术,涵盖Java 8+新特性,如CompletableFuture异步处理、Stream并行流操作,以及Reactive编程中的Reactor框架。通过具体代码示例,讲解了异步任务组合、并行流优化及响应式编程的核心概念(Flux与Mono)。同时对比了同步、CompletableFuture和Reactor三种实现方式的性能,并总结了最佳实践,帮助开发者构建高效、扩展性强的应用。资源地址:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
531 3
|
11月前
|
算法 Java 调度
Java多线程基础
本文主要讲解多线程相关知识,分为两部分。第一部分涵盖多线程概念(并发与并行、进程与线程)、Java程序运行原理(JVM启动多线程特性)、实现多线程的两种方式(继承Thread类与实现Runnable接口)及其区别。第二部分涉及线程同步(同步锁的应用场景与代码示例)及线程间通信(wait()与notify()方法的使用)。通过多个Demo代码实例,深入浅出地解析多线程的核心知识点,帮助读者掌握其实现与应用技巧。
177 1
|
11月前
|
Java
java 多线程异常处理
本文介绍了Java中ThreadGroup的异常处理机制,重点讲解UncaughtExceptionHandler的使用。通过示例代码展示了当线程的run()方法抛出未捕获异常时,JVM如何依次查找并调用线程的异常处理器、线程组的uncaughtException方法或默认异常处理器。文章还提供了具体代码和输出结果,帮助理解不同处理器的优先级与执行逻辑。
232 1
|
数据采集 存储 网络协议
Java HttpClient 多线程爬虫优化方案
Java HttpClient 多线程爬虫优化方案
|
安全 Java
深入理解Java并发编程:线程安全与性能优化
【2月更文挑战第22天】在Java并发编程中,线程安全和性能优化是两个重要的主题。本文将深入探讨这两个主题,包括线程安全的基本概念,如何实现线程安全,以及如何在保证线程安全的同时进行性能优化。
191 0
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
362 1
|
安全 Java
Java中的并发编程:理解并发性与线程安全
Java作为一种广泛应用的编程语言,在并发编程方面具有显著的优势和特点。本文将探讨Java中的并发编程概念,重点关注并发性与线程安全,并提供一些实用的技巧和建议,帮助开发人员更好地理解和应用Java中的并发机制。
225 28
下一篇
开通oss服务