IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 多线程应用(线程池单例模式) -> 正文阅读

[Java知识库]多线程应用(线程池单例模式)

线程池

一堆线程进行任务处理,主要针对大量任务需要处理的场景,使用多执行流可以提高处理效率

如果一个任务到来就创建一个线程来处理这有很大缺点:

  • 成本:总耗时=线程创建时间+任务处理时间+线程销毁时间,如果任务处理时间短,则大量时间被线程创建与销毁消耗了
  • 风险:如果有大量线程进来,则在峰值压力下系统可能会有崩溃风险

思想:线程池其实是一堆创建好的线程和一个任务队列,有任务来了就抛入线程池中,分配一个线程进行处理

线程池中的线程与任务节点数量都有最大限制,避免资源消耗.

实现:

typedef void (*handler_t)(int data);

class ThreadTask{
    private:
        int _data;//要处理的数据
        handler_t _handler;//处理数据的函数
    public:
        ThreadTask() {}
        ThreadTask(int data, handler_t handler):_data(data),
            _handler(handler){}
        void Run(){
            _handler(_data);
        }
};

class BlockQueue
{
    private:
        std::queue<ThreadTask> _queue;
        int _capacity;
        pthread_mutex_t _mutex;
        pthread_cond_t _cond_pro;
        pthread_cond_t _cond_con;
    public:
        BlockQueue(int maxq = MAXQ):_capacity(maxq){
            pthread_mutex_init(&_mutex, NULL);
            pthread_cond_init(&_cond_pro, NULL);
            pthread_cond_init(&_cond_con, NULL);
        }
        ~BlockQueue() {
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_cond_pro);
            pthread_cond_destroy(&_cond_con);
        }
        bool Push(const ThreadTask &data){
            pthread_mutex_lock(&_mutex);
            while(_queue.size() == _capacity) {
                pthread_cond_wait(&_cond_pro, &_mutex);
            }
            _queue.push(data);
            pthread_mutex_unlock(&_mutex);
            pthread_cond_signal(&_cond_con);
            return true;
        }
        bool Pop(ThreadTask *data) {
            pthread_mutex_lock(&_mutex);
            while(_queue.empty() == true) {
                pthread_cond_wait(&_cond_con, &_mutex);
            }
            *data = _queue.front();
            _queue.pop();
            pthread_mutex_unlock(&_mutex);
            pthread_cond_signal(&_cond_pro);
            return true;
        }
};


class Threadpool{
    private:
        int _max_thread;//线程最大数量
        int _max_queue;//任务队列中节点最大数量
        BlockQueue _queue;
    public:
        Threadpool(int max_thr=MAX_THREAD, int max_q=MAXQ):
            _max_thread(max_thr),
            _max_queue(max_q), _queue(max_q){
            pthread_t tid;
            int ret;
            for (int i = 0; i < max_thr; i++) {
                ret = pthread_create(&tid, NULL, thr_entry, this);
                if (ret != 0) {
                    printf("thread create error\n");
                    exit(-1);
                }
                pthread_detach(tid);
            }
        }
        static void *thr_entry(void *arg){
            Threadpool *pool = (Threadpool*)arg;
            while(1) {
                ThreadTask task;
                pool->_queue.Pop(&task);
                task.Run();
            }
        }
        bool TaskPush(const ThreadTask &task) {
            _queue.Push(task);
        }
};

单例模式

针对场景:一个类只能实例化一个对象,提供一个访问接口,也就是说一个资源在内存中只能有一份

目的:节约内存;防止数据二义;

具体实现

饿汉与懒汉模式

饿汉资源全部提前加载初始化完毕,用的时候直接用(以空间换时间)

  • 构造函数私有化,无法在类外实例化对象
  • 在类内实例化全局唯一对象,资源单独一份共享,运行前初始化,初始化过程不用考虑线程安全问题

懒汉:资源使用的时候再加载(用的比较多)

  • 构造函数私有
  • 在访问接口中加锁保护资源初始化加载过程
  • 二次检测,防止锁冲突,提高效率
  • 防止编译器过度优化,使用volatile修饰指针成员变量
//饿汉模式
class Singleton
{
   public:
        static Singleton* GetInstance()
        {
            return &_instance;
        }
    private:
        Singleton(){};
        Singleton(Singleton const&);
        static Singleton _instance;//全局的唯一对象
};
//懒汉模式
class Singleton
{
public:
     volatile static Singleton* GetInstance()
    {
        if (_instance == nullptr)
        {
            m_mutex.lock();
            if (_instance == nullptr)
            {
                _instance = new Singleton();
            }
            m_mutex.unlock();
        }
        return _instance;
    }
private:
    Singleton() {};//构造函数私有
    volatile static Singleton* _instance;//单例对象指针
    static mutex m_mutex;//互斥锁
};

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-04 10:54:21  更:2022-02-04 10:56:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:07:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码