• 黑马程序员系列第二篇 多线程(2)


    (前言:本篇文章主要依据毕向东老师的课程视频整理而成,如要详细学习,请观看毕老师视频  百度网盘链接地址:http://pan.baidu.com/s/1i3m6DrJ)

    目录:1、线程通信--生产消费者示例(线程通信安全、等待唤醒机制)    2、停止线程、及其会出现的问题、及解决的办法    3、守护线程及几个Thread的方法                   4、工作中线程的常见写法

    1、线程通信--生产消费者示例

    代码示例:

    public class ProducerConsumer {
    //需求:生产和消费行为依次进行。     设置产品为BMW   设置生产者和消费者线程各两个
        public static void main(String[] args) {
            
             Product pro=new Product();
             
            new Thread(new Producter(pro)).start();       
            new Thread(new Consumer(pro)).start();
            new Thread(new Producter(pro)).start();
            new Thread(new Consumer(pro)).start();
    
        }
    }
    class Product{
        
        private String name;
        private int No=1;
        boolean flag=false;
        
        public synchronized void set(String names){
            while(flag)
                try {
                     this.wait();//等待状态                
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }    
                  this.name=names+"---"+this.No++;
                  System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");            
                    flag=true;
                    this.notifyAll();//唤醒所有线程
        }    
        public synchronized void out(){
            while(!flag)
                try {
                    this.wait();//等待状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }        
            System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");        
                   flag=false;
                   this.notifyAll();//唤醒所有线程
        }
    }
    //生产者
    class Producter implements Runnable{
        private Product p;
        public Producter(Product pr){
            this.p=pr;
        }
        public void run(){        
          while(true){
            p.set("BMW");
          }
        }    
    }
    //消费者
    class Consumer implements Runnable{
        private Product p;
        public Consumer(Product pr){
            this.p=pr;
        }    
        public void run(){        
            while(true){
            p.out();
            }
        }
    }

    使用JDK5.0新特性改进后的代码

     1 /*JDK5.0后增加了Lock 和Condition新类特性来取代 同步和锁的繁琐操作 */
     2 public class ProducerConsumerNew {
     3 
     4     public static void main(String[] args) {
     5         
     6         Product pro=new Product();
     7         
     8        new Thread(new Producter(pro)).start();       
     9        new Thread(new Consumer(pro)).start();
    10        new Thread(new Producter(pro)).start();
    11        new Thread(new Consumer(pro)).start();
    12          
    13     }
    14 
    15 }
    16 class ProductNew{    
    17     private String name;
    18     private int No=1;
    19     boolean flag=false;
    20     
    21     private Lock lock=new ReentrantLock();
    22     private Condition con1=lock.newCondition();
    23     private Condition con2=lock.newCondition();
    24     
    25     public  void set(String name){
    26         
    27         while(flag)
    28             try {
    29                 lock.lock();
    30                 con1.wait();
    31             } catch (InterruptedException e) {
    32                 e.printStackTrace();
    33             }finally{
    34                 lock.unlock();
    35             }
    36           this.name=name+"---"+this.No++;  
    37           System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");
    38             
    39           this.flag=true;
    40           con2.signal();
    41     }
    42     
    43     public  void out(){        
    44         while(!this.flag)
    45             try {
    46                 lock.lock();
    47                 con2.wait();
    48             } catch (InterruptedException e) {
    49                 e.printStackTrace();
    50             }finally{
    51                 lock.unlock();
    52                 con1.signal();
    53             }        
    54         System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");
    55         
    56         this.flag=false;
    57     }
    58 }
    59 //生产者
    60 class ProducterNew implements Runnable{
    61     private ProductNew p;
    62     public ProducterNew(ProductNew pr){
    63         this.p=pr;
    64     }
    65     public void run(){
    66       while(true){
    67         p.set("BMW");
    68       }
    69     }    
    70 }
    71 //消费者
    72 class ConsumerNew implements Runnable{
    73     private ProductNew p;
    74     public ConsumerNew(ProductNew pr){
    75         this.p=pr;
    76     }    
    77     public void run(){
    78         while(true)
    79         p.out();
    80     }
    81 }

      

    2、停止线程、及其会出现的问题、及解决的办法    

    停止线程思路:开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run()方法结束,线程即结束。

    特殊情况:当线程处于冻结状态(wait()),就不会读取到标记,那么线程就不会结束。

    解决办法:当没有指定的方式让冻结的线程恢复到运行状态时,需要用Interrupt()方法强制清除冻结状态,再用操作标记让线程结束 

     

    一个简单的代码例子

     1 public class ThreadStop {
     2 
     3     public static void main(String[] args) {
     4         
     5         ThreadTt tt=new ThreadTt();
     6         
     7         Thread th1=new Thread(tt);
     8         Thread th2=new Thread(tt);
     9         th1.start();
    10         th2.start();
    11         int count=0;
    12         while(true){
    13             if(++count>60){     //循环来控制线程的结束
    14                 th1.interrupt();  //强制清除线程冻结状态
    15                 th2.interrupt();
    16                 break;
    17             }
    18             System.out.println(Thread.currentThread().getName()+"....run---"+count);
    19         }      
    20         System.out.println(Thread.currentThread().getName()+"....over");
    21     }
    22 }
    23 class ThreadTt implements Runnable{
    24     
    25    boolean flag=true;
    26    Lock lock=new ReentrantLock();
    27    Condition con=lock.newCondition();
    28     public synchronized void run() {
    29         
    30         while(flag){
    31             try {
    32                 wait();       //用这个方法让线程处于冻结状态
    33             } catch (InterruptedException e) {
    34                 System.out.println(e.getStackTrace());
    35                  flag=false;
    36             }
    37         System.out.println(Thread.currentThread().getName()+"...run");
    38         }
    39     }
    40 }

     

    3、守护线程及几个Thread的方法

    守护线程/用户线程:通俗而言为”后台进程”,当前台进程都结束时,后台进程自动结束;当正在运行的线程都是守护线程时,JVM自动退出。     

     

    setDaemon()方法设置守护线程,该方法必须在启动线程前调用

     

     

    Join()方法  特点:当A线程执行到了B线程的jion()方法是,A就会等待,等B线程都执行完以后,A才会执行。Jion可以用来临时加入线程执行    线程抢夺cpu执行权

     

    ToString()方法

     

    setPriority()方法 更改线程的优先级,优先级代表抢夺资源的频率高低

     

    Yield()方法  暂停当前线程的执行,去执行其它线程

     

    4、工作中线程的常见写法(用到内部类)

    不多说,看代码

     1 public class ThreadStand {
     2 
     3     public static void main(String[] args) {
     4      //工作中多线程的常见写法,构建内部类
     5         new Thread(){
     6             public void run(){
     7                 for(int i=0;i<100;i++)
     8                     System.out.println(Thread.currentThread().getName()+"....run...."+i);
     9             }
    10         }.start();
    11         
    12         for(int i=0;i<100;i++)
    13             System.out.println(Thread.currentThread().getName()+"....run...."+i);
    14         
    15         //构造内部类
    16         Runnable rn= new Runnable(){
    17             public void run() {
    18                 for(int i=0;i<100;i++)
    19                     System.out.println(Thread.currentThread().getName()+"....run...."+i);                
    20             }
    21         };  
    22         new Thread(rn).start();   
    23     }
    24 }

           

           初学者难免错误,欢迎评判指教,持续更正ing...........

  • 相关阅读:
    Python基础07
    python基础06
    python基础05
    python基础04
    python基础03
    python基础02
    python组件之wtforms
    PythonWeb框架之Flask
    Linux下yum安装Redis
    在vuex的mutations中使用vue的小技巧
  • 原文地址:https://www.cnblogs.com/blueFlowers/p/4953573.html
Copyright © 2020-2023  润新知