Count_Down

多线程实现一个累加(可以是具体业务)操作

谁都会走 提交于 2020-10-11 00:54:35
普通做法 在这个直接累加100 public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); Integer count = 100; Integer sum = 0; for (int a = 0; a < count; a++) { sum += a; Thread.sleep(100); } System.out.println(String.format("结果:%d\n耗时:%d", sum, System.currentTimeMillis() - start)); } 执行结果: 结果:4950 耗时:10054 可以看到耗时10秒; 优化方案 通过线程异步执行实现累加 public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); Integer count = 100; CountDownLatch countDownLatch = new CountDownLatch(count); AtomicInteger sum = new AtomicInteger(0); for (int a = 0;

非常有用的并发控制-倒计时器CountDownLatch

一曲冷凌霜 提交于 2020-10-06 03:44:59
CountDownLatch见名思义,即倒计时器,是多线程并发控制中非常有用的工具类,它可以控制线程等待,直到倒计时器归0再继续执行。 给你出个题,控制5个线程执行完后主线徎再往下执行,并统计5个线程的所耗时间。当然我们可以通过join的形式完成这道题,但如果我说统计100个1000个线程呢?难道要写1000个join等待吗?这显然是不现实的。 废话少说,我们来做一个例子看看上面的题怎么实现,并理解倒计时器。 首先通过new CountDownLatch(5)约定了倒计时器的数量,在这里也是线程的数量,每个线程执行完后再对倒计时器-1。countDown()方法即是对倒计时器-1,这个方法需要放在finally中,一定要保证在每个线程中得到释放,不然子线程如果因为某种原因报错倒计时器永远不会清0,则会导报主线程会一直等待。 await()方法即是主线程阻塞等待倒计器归0后再继续往下执行,当然await可以带时间进去,等待多久时间后不管倒计时器有没有归0主线程继续往下执行。 如上面的例子所示,我们输出了倒计时器最后的数字0,表示倒计时器归0了,也输出了从开始到结束所花费的时间。从这个例子可以完全理解倒计时器的含义,这个工具类在实际开发经常有用到,也很好用。 推荐去我的博客阅读更多: 1. Java JVM、集合、多线程、新特性系列教程 2. Spring MVC、Spring

leetcode多线程之按序打印

这一生的挚爱 提交于 2020-09-30 12:48:36
序 本文主要记录一下leetcode多线程之按序打印 题目 我们提供了一个类: public class Foo { public void first() { print("first"); } public void second() { print("second"); } public void third() { print("third"); } } 三个不同的线程将会共用一个 Foo 实例。 线程 A 将会调用 first() 方法 线程 B 将会调用 second() 方法 线程 C 将会调用 third() 方法 请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/print-in-order 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解 使用juc包的CountDownLatch class Foo { CountDownLatch second = new CountDownLatch(1); CountDownLatch third = new CountDownLatch(1); public Foo() { } public void

Semaphore、CountDownLatch和CyclicBarrier

独自空忆成欢 提交于 2020-08-19 13:32:00
这三者都是java并发包的工具类,提供了比synchronized更加高级的各种同步结构,可以实现更加丰富的多线程操作。 Semaphore 信号量 ,我们应该都在操作系统课程里学过,它是解决进程间通信和同步的常用工具,也是一种常见的模型。信号量是一个确定的二元组(s, q), s是正整型变量,q是初始状态为空的队列,s代表并发状态,操作系统利用信号量的状态s管理并发进程。如果s<=0,进程阻塞,如果s>0,进程继续执行。为了实现对s值的修改,操作系统提供了P、V操作原语,P的操作包括:s值减1,若s<=0,则进程阻塞,并将该进程插入到等待队列q中,V操作:s值加1,若s<=0,从等待队列中移出一个进程,解除其阻塞状态。 Java提供了经典信号量(Semaphore)的实现,它通常用于 控制线程数 来达到限制共享资源访问的目的。 下面用信号量实现生产者消费者模型来演示下用法: public class SemaphoreDemo { private static volatile int count = 0 ; private static final Semaphore full = new Semaphore(5); private static final Semaphore empty = new Semaphore(0); private static final

c#多线程总结(纯干货)

我们两清 提交于 2020-08-19 00:49:01
线程基础 创建线程 static void Main( string [] args) { Thread t = new Thread(PrintNumbers); t.Start(); // 线程开始执行 PrintNumbers(); Console.ReadKey(); } static void PrintNumbers() { Console.WriteLine( " Starting... " ); for ( int i = 1 ; i < 10 ; i++ ) { Console.WriteLine(i); } } View Code 暂停线程 class Program { static void Main( string [] args) { Thread t = new Thread(PrintNumbersWithDelay); t.Start(); PrintNumbers(); Console.ReadKey(); } static void PrintNumbers() { Console.WriteLine( " Starting... " ); for ( int i = 1 ; i < 10 ; i++ ) { Console.WriteLine(i); } } static void PrintNumbersWithDelay() {

闭锁,信号量和栅栏

孤街浪徒 提交于 2020-08-18 09:03:29
前言 jdk1.5并发库新增同步工具类,包括闭锁,信号量,循环栅栏。其本质不过是声明一个int类型volatile的变量state,来记录状态,也就是个数,通过不断的循环读取这个值,和同步的减小这个值,达到0,以达到阻塞线程和满足条件时放行的目的。 闭锁CountDownLatch 功能说明 一个例子 public class CountDownTest { private CountDownLatch countDownLatch = new CountDownLatch(3); public static void main(String[] args) throws InterruptedException { CountDownTest countDownTest = new CountDownTest(); countDownTest.test(); System.out.println("-----验证不会再改变状态,这扇门将永远保持打开-------"); countDownTest.test(); } public void test() throws InterruptedException { new Thread(() -> { try { Thread.sleep(1000); System.out.println("A搞到粉条回来了"); } catch

java内存模型-内存间交互操作

走远了吗. 提交于 2020-08-16 17:46:52
前言 本文是阅读周志明大佬的《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第12章,12.3节Java内存模型得来的读书笔记。 阅读告警😂😂😂,本文可能会有点枯燥,大部分内容都是对书中内容做一记录。示例代码可能会有不同。 一、内存间交互操作 关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存这一类的实现细节,Java内存模型中定义了8中操作,每一种操作都是原子的、不可再分的 lock(锁定):作用于主内存变量,把一个变量标识为一条线程独占的状态 unlock(解锁):作用于主内存变量,把一个处于锁定状态的变量释放,释放后的变量才可以被其他线程访问 read(读取):作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存中,以便load操作使用 load(载入):作用于工作内存的变量,把read操作从主内存中得到的变量值放入工作内存的变量副本中 use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作 assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作 store(存储):作用于工作内存的变量

Java并发编程:线程和锁的使用与解析

拟墨画扇 提交于 2020-08-13 23:01:20
线程的使用   新建线程    新建一个线程有两种方法: 继承Thread类 ,然后重写run方法; 实现Runnable接口 ,然后实现run方法。实际上Thread类也是实现的Runnable接口,再加上类只能单继承,所以推荐使用Runnable接口。示例如下: class Demo1 implements Runnable{ @Override public void run() { // 新建线程需要执行的逻辑 } } class Demo2 extends Thread{ @Override public void run() { // 新建线程需要执行的逻辑 } }    对于 Thread类,当然可以使用匿名内部类来简化写法: Thread thread= new Thread(){ public void run(){ // 新建线程需要执行的逻辑 } }; // Lambda表达式简化后 Thread thread= new Thread(()-> { // 需要执行的逻辑 }); 新建完一个线程后,就可以用对象实例来启动线程,启动后就会执行我们重写后的run方法: thread.start();    此外,Thread类有个非常重要的构造方法: public Thread(Runnable target) { init( null , target,

GoLang

杀马特。学长 韩版系。学妹 提交于 2020-08-12 20:14:34
仍然还有一些问题 还有一个重要的特性,我们还没有测试过。 Countdown 应该在第一个打印之前 sleep,然后是直到最后一个前的每一个,例如: Sleep Print N Sleep Print N-1 Sleep etc 我们最新的修改只断言它已经 sleep 了 4 次,但是那些 sleeps 可能没按顺序发生。 当你在写测试的时候,如果你没有信心,你的测试将给你足够的信心,尽管推翻它!(不过首先要确定你已经将你的更改提交给了源代码控制)。将代码更改为以下内容。 func Countdown(out io.Writer, sleeper Sleeper) { for i := countdownStart; i > 0; i-- { sleeper.Sleep() } for i := countdownStart; i > 0; i-- { fmt.Fprintln(out, i) } sleeper.Sleep() fmt.Fprint(out, finalWord) } 如果你运行测试,它们仍然应该通过,即使实现是错误的。 让我们再用一种新的测试来检查操作的顺序是否正确。 我们有两个不同的依赖项,我们希望将它们的所有操作记录到一个列表中。所以我们会为它们俩创建 同一个监视器。 type CountdownOperationsSpy struct { Calls [

django 发送手机验证码

痞子三分冷 提交于 2020-08-12 02:11:02
一、流程分析: 1.用户在项目前端,输入手机号,然后点击【获取验证码】,将手机号发到post到后台。 2.后台验证手机号是否合法,是否已被占用,如果通过验证,则生成验证码,并通过运行脚本,让短信运营商向该手机号,发送该验证码,如果没通过验证,则返回错误信息 3.用户收到短信验证码以后,再次将所有信息post到后台。 4.后台验证各个数据,通过验证则完成实名制认证,如果没通过则返回错误信息。 总结,一次实名验证,需要两次ajax+post 二、对接短信商: 1.在云片网端: 1.注册云片网 地址:https://www.yunpian.com/ 后台管理控制台页面:其中最重要的信息是APIKEY 2.开发者备案、新增签名、新增模板(模板管理) 1.云片网后台的【测试】是没有意义的,所谓的测试,就是直接给你手机发送一条短信,这算哪门子测试? 2.【签名/模板设备】页,【签名管理】点击【新增签名】,到这里会被提醒完善【开发者信息】,认证分为开发者的【公司】和【个人】,现在是开发测试阶段,可以先选择【个人】,【个人】要身份证的照片,提交照片。 3.等待认证完成的短信通知,然后按照后台的操作指引,在【签名管理】页【新增签名】,在【模板管理】页【新增模板】,这些都要等待云片网的审核,审核通过会有短信通知。 4.在云片网后台设置ip白名单,将外网ip加入白名单 获取本机外网ip最简单的方法