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

 

目录
相关文章
|
10天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
30天前
|
Java 云计算
Java多线程编程中的同步与互斥机制探析
在当今软件开发领域,多线程编程是一项至关重要的技能。本文将深入探讨Java中的同步与互斥机制,分析其在多线程环境下的应用及实现原理,帮助读者更好地理解并运用这一关键技术。
22 4
|
1天前
|
安全 Java 程序员
Java中的多线程并发编程实践
【4月更文挑战第18天】在现代软件开发中,为了提高程序性能和响应速度,经常需要利用多线程技术来实现并发执行。本文将深入探讨Java语言中的多线程机制,包括线程的创建、启动、同步以及线程池的使用等关键技术点。我们将通过具体代码实例,分析多线程编程的优势与挑战,并提出一系列优化策略来确保多线程环境下的程序稳定性和性能。
|
2天前
|
存储 缓存 安全
Java并发基础之互斥同步、非阻塞同步、指令重排与volatile
在Java中,多线程编程常常涉及到共享数据的访问,这时候就需要考虑线程安全问题。Java提供了多种机制来实现线程安全,其中包括互斥同步(Mutex Synchronization)、非阻塞同步(Non-blocking Synchronization)、以及volatile关键字等。 互斥同步(Mutex Synchronization) 互斥同步是一种基本的同步手段,它要求在任何时刻,只有一个线程可以执行某个方法或某个代码块,其他线程必须等待。Java中的synchronized关键字就是实现互斥同步的常用手段。当一个线程进入一个synchronized方法或代码块时,它需要先获得锁,如果
21 0
|
10天前
|
存储 安全 Java
java多线程之原子操作类
java多线程之原子操作类
|
11天前
|
算法 JavaScript Java
Java多线程+分治求和,太牛了
`shigen`,一位擅长Java、Python、Vue和Shell的博主,分享编程知识和成长体验。在一次面试中因对高并发问题准备不足而受挫,随后深入学习,研究了线程池和经典案例——计算1亿数字的和。采用分治策略,`shigen`实现了Java版的归并排序,并对比了Python的简洁实现。通过多线程和分段求和优化,展示了如何高效解决大数求和问题,引入了分治思想的递归任务来进一步提升性能。未来将探讨`forkjoin`框架。关注`shigen`,每天学习新知识!
17 0
Java多线程+分治求和,太牛了
|
11天前
|
Java
Java中的多线程实现:使用Thread类与Runnable接口
【4月更文挑战第8天】本文将详细介绍Java中实现多线程的两种方法:使用Thread类和实现Runnable接口。我们将通过实例代码展示如何创建和管理线程,以及如何处理线程同步问题。最后,我们将比较这两种方法的优缺点,以帮助读者在实际开发中选择合适的多线程实现方式。
19 4
|
12天前
|
Java API UED
Java中的多线程并发编程实践
【4月更文挑战第7天】在现代软件开发中,多线程技术是提高程序性能和响应速度的重要手段。Java语言提供了丰富的多线程支持,包括线程的创建、管理和同步机制。本文将深入探讨Java多线程的基本概念、实现方式以及常见的并发问题,并通过实例代码演示如何高效地利用多线程技术。
10 1
|
16天前
|
Java 测试技术 开发者
Java中的多线程实现与性能优化
【4月更文挑战第3天】 在现代软件开发中,多线程技术是提高程序执行效率和响应速度的重要手段。Java语言提供了丰富的多线程支持,包括原生的Thread类和Runnable接口,以及java.util.concurrent包中的高级并发工具。然而,不当的多线程使用可能导致程序性能下降、死锁等问题。本文将探讨Java中多线程的具体实现方法,并着重讨论如何通过合理的设计和编码实践来优化多线程应用的性能。我们将分析线程创建与管理的基本概念,深入理解同步机制,并探讨并发集合、线程池等高级特性的使用。文章的目的是为开发者提供一套实用的多线程性能优化策略,帮助他们在面对并发编程挑战时能够编写出更加高效、稳定
14 1
|
17天前
|
安全 Java 容器
Java并发编程:实现高效、线程安全的多线程应用
综上所述,Java并发编程需要注意线程安全、可见性、性能等方面的问题。合理使用线程池、同步机制、并发容器等工具,可以实现高效且线程安全的多线程应用。
14 1