多线程学习之多线程访问共同资源(队列,多线程,锁机制)实例

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

消费者线程体

  1 /**
  2  *
  3  */
  4 package com.benxq.Queue;
  5
  6 import java.text.SimpleDateFormat;
  7 import java.util.Date;
  8 import java.util.concurrent.BlockingQueue;
  9 import java.util.concurrent.LinkedBlockingQueue;
 10 import java.util.concurrent.TimeUnit;
 11
 12
 13 /**
 14  * Created by qucf on 2015年10月22日.
 15  */
 16 public class MyThread implements Runnable{
 17
 18     //多线程缓存队列
 19     private BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
 20
 21     //队列中的资源数
 22     private Integer count=0;
 23
 24     //线程锁
 25     private Object object =new Object();
 26
 27     //生产者完成标示
 28     private boolean flag=false;
 29
 30     //线程构造器
 31     public MyThread(BlockingQueue<String> queue){
 32         this.queue=queue;
 33     }
 34
 35     //获取线程对象
 36     public Object getObjectByLock(){
 37         return this.object;
 38     }
 39
 40     //标志着生产者生产结束
 41     public void setFlag(){
 42         this.flag=true;
 43     }
 44
 45     //队列数据加一个
 46     public void setCount(){
 47         //当队列小于0时 默认恢复到0
 48         if(count<0){
 49             count=0;
 50         }
 51         count++;
 52     }
 53
 54     @Override
 55     public void run() {
 56         while(true){
 57             //获取当前线程的名字
 58             String threadName=Thread.currentThread().getName();
 59
 60             //资源处理完毕 和生产者生产结束  跳出循环
 61             if(count==0&& flag){
 62                 break;
 63             }
 64
 65             try {
 66                 //从队列中获取数据,如果没有数据等待100毫秒,如果100毫秒后还是没有数据 则返回null
 67                 String pollInteger=queue.poll(1000, TimeUnit.MILLISECONDS);
 68
 69                 //如果取出的数据为空,则暂停本次循环,进行下次循环
 70                 if(pollInteger==null){
 71                     continue;
 72                 }
 73
 74                 //如果队列中的数据为0 则暂停本次循环执行下次循环
 75                 if(count<=0){
 76                     continue;
 77                 }
 78
 79                 //队列中的数据减1
 80                 count--;
 81
 82                 //获取执行时间点
 83                 SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
 84
 85                 //从队列中消费数据
 86                 System.out.println("MyThread-->"+threadName+"-->"+pollInteger+"-->"+sd.format(new Date()));
 87
 88
 89             } catch (InterruptedException e) {
 90                 // TODO Auto-generated catch block
 91                 e.printStackTrace();
 92             }
 93
 94
 95         }
 96         //当消费结束后 唤醒该锁锁住的所有线程
 97         synchronized (object) {
 98             object.notifyAll();
 99             System.out.println("唤醒线程"+Thread.currentThread().getName());
100         }
101     }
102
103 }

主方法(模拟网络请求)

/**
 *
 */
package com.benxq.Queue;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by qucf on 2015年10月22日.
 */
public class Test {

    //模拟消费线程队列
    private static BlockingQueue<String> queue=new LinkedBlockingQueue<String>();

    //模拟网络请求
    public static void main(String[] args) {

        MyThread myThread=new MyThread(queue);

        //线程池 开启 5个消费线程
        ExecutorService es=Executors.newFixedThreadPool(5);
        //开启5个线程
        for (int i = 0; i < 5; i++) {
            es.execute(myThread);
        }

        //模拟生产线程
        try {
            for (int i = 0; i <= 100; i++) {
                queue.put(i+"benxq");
                myThread.setCount();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            myThread.setFlag();
        }

        //生产结束后,网络请求线程被阻塞
        synchronized (myThread.getObjectByLock()) {
            try {
                myThread.getObjectByLock().wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //当线程被唤醒后,执行完毕
        SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        System.out.println("执行完毕"+sd.format(new Date()));
    }
}

测试结果

MyThread-->pool-1-thread-3-->4benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->1benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->2benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->5benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->3benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->8benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->0benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->9benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->7benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->12benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->6benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->14benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->15benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->16benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->17benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->18benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->19benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->20benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->13benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->11benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->10benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->23benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->24benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->22benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->26benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->27benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->29benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->21benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->30benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->31benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->32benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->33benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->34benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->35benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->37benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->36benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->28benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->39benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->40benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->41benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->42benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->43benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->44benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->45benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->46benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->47benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->48benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->49benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->25benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->51benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->52benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->54benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->55benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->56benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->50benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->58benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->59benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->60benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->61benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->62benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->38benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->63benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->64benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->65benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->57benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->67benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->68benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->53benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->70benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->71benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->72benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->69benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->75benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->76benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->66benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->77benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->78benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->80benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->74benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->81benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->82benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->83benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->84benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->85benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->86benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->87benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->88benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->73benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->90benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->91benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->92benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->93benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->94benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->89benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-1-->96benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->79benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-5-->98benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-3-->97benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-4-->95benxq-->2015-10-22 11:12:55
MyThread-->pool-1-thread-2-->100benxq-->2015-10-22 11:12:55
唤醒线程pool-1-thread-5
MyThread-->pool-1-thread-1-->99benxq-->2015-10-22 11:12:55
唤醒线程pool-1-thread-2
唤醒线程pool-1-thread-4
唤醒线程pool-1-thread-3
唤醒线程pool-1-thread-1
执行完毕2015-10-22 11:12:55
时间: 2024-10-13 04:40:46

多线程学习之多线程访问共同资源(队列,多线程,锁机制)实例的相关文章

SpringBoot学习5:访问静态资源

springboot默认从项目的resources里面的static目录下或者webapp目录下访问静态资源 方式一:在resources下新建static文件(文件名必须是static) 在浏览器中访问 方式二:新建webapp文件夹 在浏览器中访问 原文地址:https://www.cnblogs.com/duanrantao/p/10352643.html

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

模拟场景:main方法为网络请求线程(也叫生产者线程),在网络请求线程中开启四个线程(消费者线程),进行高效处理队列中的共同资源(生产者线程生产的共同资源),等待资源处理完毕,网络请求线程执行结束,响应客户端. 消费者线程的线程体 1 import java.text.SimpleDateFormat; 2 import java.util.Date; 3 import java.util.concurrent.BlockingQueue; 4 import java.util.concurre

java多线程学习(3)

1)竞争条件 在实际的多线程应用中,通常会有两个或多个线程需要对共同的对象进行共享访问,如果两个线程访问相同的对象,而且每一个都调用了一个会改变对象状态的方法, 那么,线程就会相互倾轧.根据各个线程访问数据的不同顺序,可能会产生腐蚀现象.这种情况通常称为竞争条件. 2)同步 为了多个线程对共享数据的腐蚀,就需要对数据的存取实现同步:常用的同步方法有3种: 1.Reenlock 用Reenlock保护代码块的基本机构如下: 1 Lock myLock=new ReenLock; 2 3 myLoc

Java基础学习之-多线程学习知识点的学习

Java语言从设计之初就把多线程作为语言的核心, 至少从以下几点可以看出: 1. Object对象的wait和notify机制. 2. Thread类在lang包中. 3. synchronized volatile关键字. 虽然多线程是Java语言本身的特性,但是线程并不是Java语言独有的东西,而是操作系统的特性.Java在语言层面进行了封装,使其使用更简单. 多线程存在的价值在哪里呢? 内存读写,磁盘IO, 网络传输的速率远远低于CPU处理数据的速度.所以在大部分场景下,CPU是闲置的.有

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

多线程学习(二)

多线程概念  并发性和并行性  在单个处理器的多线程进程中,处理器可以在线程之间切换执行资源,从而执行并 发. 在共享内存的多处理器环境内的同一个多线程进程中,进程中的每个线程都可以在一 个 单独的处理器上并发运行,从而执行并行.如果进程中的线程数不超过处理器的数 目, 则线程的支持系统和操作环境可确保每个线程在不同的处理器上执行.例如,在 线程数 和处理器数目相同的矩阵乘法中,每个线程和每个处理器都会计算一行结果. 多线程结构一览 传统的UNIX已支持多线程的概念.每个进程都包含一个线程,因此

C#多线程学习(一) 多线程的相关概念

什么是进程?    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?    线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 什么是多线程?    多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 多线程的好处:    可以提

java多线程学习笔记

一.线程的创建 1.  通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2.  通过实现Runnable接口,实例化Thread类 但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有.此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程.(start()可以协调系统的资源)

C#多线程学习(一) 多线程的相关概念(转)

什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 什么是多线程?多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 多线程的好处:可以提高CPU的利用率.在多线程程序中

Java多线程学习

写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线