java多线程基础-编程思维

1. 概念 程序的并发和并行 : 并发:指两个或多个事件在同一个时间段内发生 并行:指两个或多个事件在同一时刻发生(同时发生)。 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每 一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分 时交替运行的时间是非常短的。 而在多个 CPU 系统中,

synchronized原理-编程思维

初学习Java的时候,synchronized是我解决同步问题的神器,只需在方法上,或者在代码里面使用synchronized,就可以解决数据并发问题,但是,随着学习的进行知道synchronized是一个重量级锁,相对于Lock,它会显得笨重,所以后面渐渐的不再使用synchronized。 随着Javs SE 1.6对synchronized进行的各种优化后,synchronized 的实现

多线程学习笔记(一)-编程思维

package com.thread; /** * 创建一个子线程输出从1~100的自然数 * 创建多线程的第一种方式,继承Thread类 * getName获取当前线程的名称 * setName设置当前线程的名称 * start启动子线程 * yield当前线程会释放cpu资源,如果没有其他线程占用那么该线程还会继续执行,如果有其他线程那么可能会被其他线程抢占 * join

实现多线程的方式runnable-编程思维

package com.thread.runnable; /** * 实现多线程的方式有继承Thread类和实现Runnable接口两种方式 * 哪种方式更好呢?实现的方式由于继承的方式。 * 原因:1.避免了Java但继承的局限性 * 2.如果多个线程要操作同一份资源,实现接口的方式更适合 * @author Administrator * */public class TestRun

线程池实例:使用executors和threadpoolexecutor-编程思维

线程池负责管理工作线程,包含一个等待执行的任务队列。线程池的任务队列是一个Runnable集合,工作线程负责从任务队列中取出并执行Runnable对象。 java.util.concurrent.executors 提供了 java.util.concurrent.executor 接口的一个Java实现,可以创建线程池。下面是一个简单示例: 首先创建一个Runable 类: WorkerThr

future task cancel-编程思维

1 FutureTask.cancel 干了啥 //有一个入参,需要说明task是否是可中断的 public boolean cancel(boolean mayInterruptIfRunning) { if (state != NEW) return false; if (mayInterruptIfRunning)

同步程序中调用异步的方法-编程思维

我们平时碰到很多,同步的主程序中需要用到一些工具类是异步的,这样主程序还不能加上异步的 task等标识,就会报错.而直接调用似乎又等不到返回结果. 将调用包装在Task.Run<>(async () => await FunctionAsync()); 实际winform 项目内参考的下边的例子 作为备忘 public class LogReader { ILo

《linux多线程服务端编程:使用muduo c++网络库》上市半年重印两次,总印数达到了9000册-编程思维

《Linux多线程服务端编程:使用muduo C++网络库》这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错的成绩。本书购买方式见配套网站 http://chenshuo.com/book 。 以下谈一谈这本书的写作背景与内容取舍的原因。 参加工作以来,我编写并维护了若干C++/Java多线程网络服务程序,这本书总结

用条件变量实现事件等待器的正确与错误做法-编程思维

TL;DR 如果你能一眼看出 https://gist.github.com/chenshuo/6430925 中的那 8 个 Waiter classes 哪些是对的哪些是错的,本文就不必看了。 前几天,我发了一条微博 http://weibo.com/1701018393/A7FrW7ZVd ,质疑某本书对 Pthreads 条件变量的封装是错的,因为它没有把 mutex 的 lock()/

关于多次重复网络请求问题-编程思维

问题分析 一个页面,可以通过点击不同的模块获取相应的数据。但是,当用户频繁点击的时候,有的模块网络请求数据返回会比较慢,这个时候返回的数据就会覆盖当前模块的数据。 解决方法 加锁处理 切换模块时,会对同一个API进行多次请求,但因为调用的接口都是一样的,所以最好就是加上锁,防止重复请求造成网络资源浪费。 @synchronized (self) {//加锁,避免数组重复创建添加等问题

证明task线程是来源于线程池的,线程重用-编程思维

1、线程池是单例的,全局唯一的,设置线程池最大活跃线程数是5,设置后,允许同时并发的Task只有5个,我们开启100个task去做任务,从最后的输出结果看到,虽然开启了100个task,但是线程id始终是那5个如图所示 2、结论:证明task是来源于线程池的,而且线程是重用的 namespace task_threadpool { class Program {

异步的学习-编程思维

第一层:什么场景下需要异步 大量写操作占用了过多的资源,影响了系统的正常运行; 写操作异步后,不影响主流程,允许适当延迟; 第二层:异步的外功心法 本文提到了四种异步方式: 线程池模式 本地内存 + 定时任务 MQ 模式 Agent 服务 + MQ 模式 它们的共同特点是:将写操作命令存储在一个池子后,立刻响应给前端,减少写动作的耗时。任务服务异步从池子里获取任务后执行。

c++ 多线程的错误和如何避免(15)-编程思维

除非绝对需要,否则使用无锁架构 复杂性中有一些东西吸引了每一位工程师。与常规同步机制(如互斥锁、条件变量、异步等)相比,无锁编程听起来非常性感。然而,与我交谈过的每一位经验丰富的 C++ 开发人员都认为,使用无锁编程作为首要手段是一种过早的优化形式,可能会在最合适的时候再次困扰你(想想当你没有完整的堆转储时,生产会崩溃!)。 在我的 C++ 职业生涯中,只有一项技术需要无锁代码的性能,因为我们处

c++ 多线程的错误和如何避免(5)-编程思维

要记得对加锁的临界区解锁 前提:在多个线程共享一块资源或者数据时,我们需要加上互斥锁来保护临界区(否则出现数据未定义的行为) 问题:我们往往在写了很多代码之后忘记 unlock 互斥锁,那么等待该资源的所有其他线程将被无限期地阻塞,程序可能会挂起 解决方法:使用 RAII 类型的 std::lock_guard 对象来自动释放锁,如下: void CallHome(string message

c++ 多线程的错误和如何避免(6)-编程思维

加锁的临界区要尽可能的紧凑和小型 问题分析: 当一个线程在临界区内执行时,所有其他试图进入临界区的线程都会被阻止,所以我们应该保证临界区尽可能的小。比如, void CallHome(string message) { std::lock_guard<std::mutex> lock(mu); // Start of Critical Section - to protect

c++ 多线程的错误和如何避免(7)-编程思维

要以相同顺序获取多个锁 多线程在加锁解锁时,可能会出现死锁问题,比如, 线程 1 在加锁 mutex A 后,继续尝试获取 mutex B,而 mutex B 已经被线程 2 获取,而线程 2 在等待获取 mutex A,mutex B 只有线程 2 获取 mutex  A 后才能解锁, 这就导致线程 1 和线程 2 互相等待锁,而这一操作就是死锁情况,容易导致程序挂起。    使用代码模拟死

c++ 多线程的错误和如何避免(9)-编程思维

有时候使用 std::atomic 比使用 mutexes 更高效 问题分析:使用多线程更新一些简单数据时,比如 int 型,bool 型等等,可以使用 std::atomic,这比 mutex 来得更为高效。 比如,我们一般这样用: int counter; .... mu.lock(); counter++; mu.unlock(); 现在,我们可以这样用, std::atomic&l

c++ 多线程的错误和如何避免(10)-编程思维

线程中的异常可以使用 std::rethrow_exception 抛给主线程 问题分析:一个线程中抛出的异常是没法被另一个线程捕获的。假如我们在主线程中创建一个子线程,子线程中的函数抛出了异常,主线程的 catch 是不会触发,如下, #include<iostream> #include<thread> #include<exception> #incl