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

本文涉及的产品
文本翻译,文本翻译 100万字符
图片翻译,图片翻译 100张
文档翻译,文档翻译 1千页
简介: 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() ; 
 
   }
}

 

目录
相关文章
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
3天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
3天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
3天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
37 2
|
20天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
20天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
43 3
|
7月前
|
安全 Java
深入理解Java并发编程:线程安全与性能优化
【2月更文挑战第22天】在Java并发编程中,线程安全和性能优化是两个重要的主题。本文将深入探讨这两个主题,包括线程安全的基本概念,如何实现线程安全,以及如何在保证线程安全的同时进行性能优化。
65 0
|
7月前
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
4月前
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
71 1
|
5月前
|
安全 Java 开发者
Java并发编程中的线程安全问题及解决方案探讨
在Java编程中,特别是在并发编程领域,线程安全问题是开发过程中常见且关键的挑战。本文将深入探讨Java中的线程安全性,分析常见的线程安全问题,并介绍相应的解决方案,帮助开发者更好地理解和应对并发环境下的挑战。【7月更文挑战第3天】
109 0