多线程访问共同资源(队列,多线程,锁机制)

模拟场景:main方法为网络请求线程(也叫生产者线程),在网络请求线程中开启四个线程(消费者线程),进行高效处理队列中的共同资源(生产者线程生产的共同资源),等待资源处理完毕,网络请求线程执行结束,响应客户端。

消费者线程的线程体

技术分享
  1 import java.text.SimpleDateFormat;
  2 import java.util.Date;
  3 import java.util.concurrent.BlockingQueue;
  4 import java.util.concurrent.LinkedBlockingQueue;
  5 import java.util.concurrent.TimeUnit;
  6 
  7 /**
  8  * 【1】实现Runnable接口,重写run方法。
  9  * 【2】run方法内的逻辑代码就是线程体
 10  * 【3】创建线程类的对象
 11  * 【4】创建线程类的代理对象
 12  * 【5】代理对象调用start(),启动线程
 13  * @author it-c-1201
 14  *
 15  */
 16 public class MyThread implements Runnable{
 17     //多线程访问共同资源的队列
 18     private  BlockingQueue<String> a = new LinkedBlockingQueue<String>();
 19     
 20     //队列中共同资源的个数
 21     private Integer count=0;
 22     
 23     //线程锁
 24     private Object object=new Object();
 25     
 26     //生产者生产完成标示<false 未生产完成,true 生产完成>
 27     private boolean flag=false;
 28     
 29     //线程类构造器。
 30     public MyThread(BlockingQueue<String> a){
 31         this.a=a;
 32     }
 33     
 34     //获取线程锁对象
 35     public Object getObjectByLock(){
 36         return this.object;
 37     }
 38     
 39     //标志生产者生产结束
 40     public void setFlag(){
 41         this.flag=true;
 42     }
 43 
 44     //队列数据加一个
 45     public void setCount(){
 46         //当出现队列数据小于1的情况,恢复队列中数据个数为0
 47         if(count<0){
 48             count=0;
 49         }
 50         count++;
 51     }
 52     
 53     //线程体
 54     public void run() {
 55         //消费
 56         while(true){
 57             //获取当前线程名字
 58             String threadName=Thread.currentThread().getName();
 59             
 60             //资源处理完毕&&生产者停止生产,则跳出死循环
 61             if(count==0&&flag){
 62                 break;
 63             }
 64             
 65             
 66             String pollInteger;
 67             try {
 68                 //从队列中获取数据。如果没有数据等待100毫秒,100毫秒后还是无数据,返回null
 69                 pollInteger = a.poll(100, TimeUnit.MILLISECONDS);
 70                 
 71                 //如果取出的数据为空,则暂停本次循环,进行下次循环(后边代码不执行)
 72                 if(pollInteger==null){
 73                     continue;
 74                 }
 75                 
 76                 //如果队列中资源个数为0,则暂停本次循环,进行下次循环
 77                 if(count==0||count<0){
 78                     continue;
 79                 }
 80                 
 81                 //说明从队列中取出数据,队列中数据个数减一
 82                 count--;    
 83                 
 84                 //获取执行时间点
 85                 SimpleDateFormat aDateFormat=new SimpleDateFormat("HH:mm:ss SS");
 86                 Date date=new Date();
 87                 String dateString=aDateFormat.format(date);
 88                 //模拟消费队列中获取的数据
 89                 System.out.println("MyThread.run(-->)"+threadName+"【"+pollInteger+"】  时间: "+dateString);
 90             } catch (InterruptedException e) {
 91                 // TODO Auto-generated catch block
 92                 e.printStackTrace();
 93             }
 94             
 95         }
 96         
 97         //唤醒所有线程
 98         synchronized(object){
 99             //唤醒该锁锁住的所有线程【证明没有数据要处理了,main方法中挂起的线程(模拟的网络请求线程)被唤醒,main方法执行结束】
100             object.notifyAll();
101             String tString=Thread.currentThread().getName();
102             System.out.println("MyThread.run(-->)"+tString+"notfyAll()");
103         }
104         
105     }
106     
107     
108 }
View Code

main方法(模拟的网络请求线程)

技术分享
 1 import java.text.SimpleDateFormat;
 2 import java.util.Date;
 3 import java.util.concurrent.BlockingQueue;
 4 import java.util.concurrent.LinkedBlockingQueue;
 5 
 6 
 7 public class Test {
 8     
 9     //模拟多线程消费的共同资源
10     private static BlockingQueue<String> a = new LinkedBlockingQueue<String>();
11     
12     //模拟的网络请求来要执行的方法
13     public static void main(String[] args) {
14         //新建线程对象
15         MyThread myThread=new MyThread(a);
16         
17         
18         //开启四个消费线程
19         for(int i=0;i<4;i++){
20             Thread aThread=new Thread(myThread);
21             aThread.setName("THREAD"+i);
22             aThread.start();
23         }
24         
25         //模拟生产线程
26         try {
27             for(int i=0;i<100;i++){
28                     //往队列中加数据
29                     a.put(i+"sxf");
30                     //队列中数据个数加1
31                     myThread.setCount();
32                 }
33             } catch (InterruptedException e) {
34                 // TODO Auto-generated catch block
35                 e.printStackTrace();
36             }finally{
37                 myThread.setFlag();
38             }
39                         
40                 
41         
42         //模拟当生产完毕后,网络请求线程也叫生产线程被阻塞
43         synchronized (myThread.getObjectByLock()) {
44             try {
45                 myThread.getObjectByLock().wait();
46             } catch (InterruptedException e) {
47                 // TODO Auto-generated catch block
48                 e.printStackTrace();
49             }
50         }
51         
52         //模拟网络请求线程被唤醒后,执行完毕,向客户端响应数据
53         SimpleDateFormat aDateFormat=new SimpleDateFormat("HH:mm:ss SS");
54         Date date=new Date();
55         String dateString=aDateFormat.format(date);
56         System.out.println("Test.main(完成时间:)"+dateString);
57     }
58 }
View Code

 测试结果

技术分享
  1 MyThread.run(-->)THREAD2【2sxf】  时间: 19:39:06 127
  2 MyThread.run(-->)THREAD3【0sxf】  时间: 19:39:06 127
  3 MyThread.run(-->)THREAD0【1sxf】  时间: 19:39:06 127
  4 MyThread.run(-->)THREAD2【4sxf】  时间: 19:39:06 128
  5 MyThread.run(-->)THREAD0【6sxf】  时间: 19:39:06 128
  6 MyThread.run(-->)THREAD1【3sxf】  时间: 19:39:06 127
  7 MyThread.run(-->)THREAD2【7sxf】  时间: 19:39:06 128
  8 MyThread.run(-->)THREAD0【8sxf】  时间: 19:39:06 128
  9 MyThread.run(-->)THREAD3【5sxf】  时间: 19:39:06 128
 10 MyThread.run(-->)THREAD2【10sxf】  时间: 19:39:06 128
 11 MyThread.run(-->)THREAD3【12sxf】  时间: 19:39:06 129
 12 MyThread.run(-->)THREAD1【9sxf】  时间: 19:39:06 128
 13 MyThread.run(-->)THREAD3【14sxf】  时间: 19:39:06 129
 14 MyThread.run(-->)THREAD1【15sxf】  时间: 19:39:06 129
 15 MyThread.run(-->)THREAD3【16sxf】  时间: 19:39:06 129
 16 MyThread.run(-->)THREAD2【13sxf】  时间: 19:39:06 129
 17 MyThread.run(-->)THREAD0【11sxf】  时间: 19:39:06 129
 18 MyThread.run(-->)THREAD3【18sxf】  时间: 19:39:06 129
 19 MyThread.run(-->)THREAD2【19sxf】  时间: 19:39:06 129
 20 MyThread.run(-->)THREAD0【20sxf】  时间: 19:39:06 129
 21 MyThread.run(-->)THREAD3【21sxf】  时间: 19:39:06 129
 22 MyThread.run(-->)THREAD2【22sxf】  时间: 19:39:06 129
 23 MyThread.run(-->)THREAD1【17sxf】  时间: 19:39:06 129
 24 MyThread.run(-->)THREAD3【24sxf】  时间: 19:39:06 129
 25 MyThread.run(-->)THREAD0【23sxf】  时间: 19:39:06 129
 26 MyThread.run(-->)THREAD2【25sxf】  时间: 19:39:06 129
 27 MyThread.run(-->)THREAD1【26sxf】  时间: 19:39:06 129
 28 MyThread.run(-->)THREAD2【29sxf】  时间: 19:39:06 129
 29 MyThread.run(-->)THREAD0【28sxf】  时间: 19:39:06 129
 30 MyThread.run(-->)THREAD3【27sxf】  时间: 19:39:06 129
 31 MyThread.run(-->)THREAD1【30sxf】  时间: 19:39:06 129
 32 MyThread.run(-->)THREAD2【31sxf】  时间: 19:39:06 130
 33 MyThread.run(-->)THREAD0【32sxf】  时间: 19:39:06 130
 34 MyThread.run(-->)THREAD3【33sxf】  时间: 19:39:06 130
 35 MyThread.run(-->)THREAD1【34sxf】  时间: 19:39:06 130
 36 MyThread.run(-->)THREAD2【35sxf】  时间: 19:39:06 130
 37 MyThread.run(-->)THREAD0【36sxf】  时间: 19:39:06 130
 38 MyThread.run(-->)THREAD3【37sxf】  时间: 19:39:06 130
 39 MyThread.run(-->)THREAD1【38sxf】  时间: 19:39:06 130
 40 MyThread.run(-->)THREAD2【39sxf】  时间: 19:39:06 130
 41 MyThread.run(-->)THREAD0【40sxf】  时间: 19:39:06 130
 42 MyThread.run(-->)THREAD3【41sxf】  时间: 19:39:06 130
 43 MyThread.run(-->)THREAD1【42sxf】  时间: 19:39:06 130
 44 MyThread.run(-->)THREAD2【43sxf】  时间: 19:39:06 130
 45 MyThread.run(-->)THREAD0【44sxf】  时间: 19:39:06 130
 46 MyThread.run(-->)THREAD3【45sxf】  时间: 19:39:06 130
 47 MyThread.run(-->)THREAD1【46sxf】  时间: 19:39:06 130
 48 MyThread.run(-->)THREAD2【47sxf】  时间: 19:39:06 130
 49 MyThread.run(-->)THREAD0【48sxf】  时间: 19:39:06 130
 50 MyThread.run(-->)THREAD3【49sxf】  时间: 19:39:06 130
 51 MyThread.run(-->)THREAD1【50sxf】  时间: 19:39:06 130
 52 MyThread.run(-->)THREAD2【51sxf】  时间: 19:39:06 130
 53 MyThread.run(-->)THREAD0【52sxf】  时间: 19:39:06 130
 54 MyThread.run(-->)THREAD3【53sxf】  时间: 19:39:06 130
 55 MyThread.run(-->)THREAD1【54sxf】  时间: 19:39:06 130
 56 MyThread.run(-->)THREAD2【55sxf】  时间: 19:39:06 130
 57 MyThread.run(-->)THREAD0【56sxf】  时间: 19:39:06 130
 58 MyThread.run(-->)THREAD3【57sxf】  时间: 19:39:06 130
 59 MyThread.run(-->)THREAD1【58sxf】  时间: 19:39:06 130
 60 MyThread.run(-->)THREAD3【61sxf】  时间: 19:39:06 131
 61 MyThread.run(-->)THREAD2【59sxf】  时间: 19:39:06 131
 62 MyThread.run(-->)THREAD0【60sxf】  时间: 19:39:06 131
 63 MyThread.run(-->)THREAD1【62sxf】  时间: 19:39:06 131
 64 MyThread.run(-->)THREAD3【63sxf】  时间: 19:39:06 131
 65 MyThread.run(-->)THREAD0【65sxf】  时间: 19:39:06 131
 66 MyThread.run(-->)THREAD1【66sxf】  时间: 19:39:06 131
 67 MyThread.run(-->)THREAD3【67sxf】  时间: 19:39:06 131
 68 MyThread.run(-->)THREAD0【68sxf】  时间: 19:39:06 131
 69 MyThread.run(-->)THREAD1【69sxf】  时间: 19:39:06 131
 70 MyThread.run(-->)THREAD3【70sxf】  时间: 19:39:06 131
 71 MyThread.run(-->)THREAD2【64sxf】  时间: 19:39:06 131
 72 MyThread.run(-->)THREAD0【71sxf】  时间: 19:39:06 131
 73 MyThread.run(-->)THREAD2【74sxf】  时间: 19:39:06 132
 74 MyThread.run(-->)THREAD3【73sxf】  时间: 19:39:06 131
 75 MyThread.run(-->)THREAD0【75sxf】  时间: 19:39:06 132
 76 MyThread.run(-->)THREAD2【76sxf】  时间: 19:39:06 132
 77 MyThread.run(-->)THREAD0【78sxf】  时间: 19:39:06 132
 78 MyThread.run(-->)THREAD2【79sxf】  时间: 19:39:06 132
 79 MyThread.run(-->)THREAD0【80sxf】  时间: 19:39:06 132
 80 MyThread.run(-->)THREAD2【81sxf】  时间: 19:39:06 132
 81 MyThread.run(-->)THREAD0【82sxf】  时间: 19:39:06 132
 82 MyThread.run(-->)THREAD2【83sxf】  时间: 19:39:06 132
 83 MyThread.run(-->)THREAD0【84sxf】  时间: 19:39:06 132
 84 MyThread.run(-->)THREAD2【85sxf】  时间: 19:39:06 132
 85 MyThread.run(-->)THREAD0【86sxf】  时间: 19:39:06 132
 86 MyThread.run(-->)THREAD2【87sxf】  时间: 19:39:06 132
 87 MyThread.run(-->)THREAD0【88sxf】  时间: 19:39:06 132
 88 MyThread.run(-->)THREAD2【89sxf】  时间: 19:39:06 132
 89 MyThread.run(-->)THREAD0【90sxf】  时间: 19:39:06 132
 90 MyThread.run(-->)THREAD2【91sxf】  时间: 19:39:06 132
 91 MyThread.run(-->)THREAD1【72sxf】  时间: 19:39:06 131
 92 MyThread.run(-->)THREAD0【92sxf】  时间: 19:39:06 133
 93 MyThread.run(-->)THREAD3【77sxf】  时间: 19:39:06 132
 94 MyThread.run(-->)THREAD2【93sxf】  时间: 19:39:06 133
 95 MyThread.run(-->)THREAD0【95sxf】  时间: 19:39:06 133
 96 MyThread.run(-->)THREAD1【94sxf】  时间: 19:39:06 133
 97 MyThread.run(-->)THREAD3【96sxf】  时间: 19:39:06 133
 98 MyThread.run(-->)THREAD0【98sxf】  时间: 19:39:06 133
 99 MyThread.run(-->)THREAD2【97sxf】  时间: 19:39:06 133
100 MyThread.run(-->)THREAD3notfyAll()
101 MyThread.run(-->)THREAD2notfyAll()
102 MyThread.run(-->)THREAD0notfyAll()
103 MyThread.run(-->)THREAD1【99sxf】  时间: 19:39:06 133
104 MyThread.run(-->)THREAD1notfyAll()
105 Test.main(完成时间:)19:39:06 133
View Code

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。