多线程

Junit单元测试多线程的问题

旧城冷巷雨未停 提交于 2020-03-23 05:33:02
今天下午很快完成了一个接口的监控功能,然后屁颠屁颠地用Junit开始单元测试。然后我就开始陷入崩溃的边缘... 监控结束后需要将监控结果以邮件的形式发送给运营的小伙伴维护,前面测试还是很顺利,到了开多线程发邮件时就不行了, 程序也不报错,也接收不到邮件。然后改代码再测试,再冥思一会儿,再改再测试,还是无果,最后选择度娘一下,结论是: Junit单元测试不支持多线程 然后 ,整个人都不好了...浪费了我好多时间,就是因为这个!!! 虽然知道了结果,但是笔者还是需要亲自验证一下。 /** * @Title: TestDoWork.java * @Describe: * @author: Mr.Yanphet * @Email: mr_yanphet@163.com * @date: 2016年8月15日 下午5:50:03 * @version: 1.0 */ public class TestDoWork { class DoWork implements Runnable { @Override public void run() { for (int i = 0; i < 10000; i++) { long milliSecond = System.currentTimeMillis(); System.out.println("i=" + i + ",milliSecond=

Linux 多线程通信

耗尽温柔 提交于 2020-03-23 02:40:21
摘自资料(linux 与Windows不同) 线程间无需特别的手段进行通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同一时候使用。只是要注意的是线程间须要做好同步,一般用mutex。能够參考一些比較新的UNIX/Linux编程的书,都会提到Posix线程编程,比方《UNIX环境高级编程(第二版)》、《UNIX系统编程》等等。 linux的消息属于IPC,也就是进程间通信,线程用不上。 linux用pthread_kill对线程发信号。 另:windows下不是用post..(你是说PostMessage吗?)进行线程通信的吧? windows用PostThreadMessage进行线程间通信,但实际上极少用这样的方法。还是利用同步多一些 LINUX下的同步和Windows原理都是一样的。只是Linux下的singal中断也非常好用。 用好信号量,共享资源就能够了。 使用多线程的理由之中的一个是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而执行于一个进程中的多个线程,它们彼此之间使用同样的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,并且

多线程(三):线程安全

喜夏-厌秋 提交于 2020-03-23 02:38:50
一.一个典型的Java线程安全例子 1 public class ThreadTest { 2 3 public static void main(String[] args) { 4 Account account = new Account("123456", 1000); 5 DrawMoneyRunnable drawMoneyRunnable = new DrawMoneyRunnable(account, 700); 6 Thread myThread1 = new Thread(drawMoneyRunnable); 7 Thread myThread2 = new Thread(drawMoneyRunnable); 8 myThread1.start(); 9 myThread2.start(); 10 } 11 12 } 13 14 class DrawMoneyRunnable implements Runnable { 15 16 private Account account; 17 private double drawAmount; 18 19 public DrawMoneyRunnable(Account account, double drawAmount) { 20 super(); 21 this.account = account; 22

_beginThreadex创建多线程解读

非 Y 不嫁゛ 提交于 2020-03-23 02:32:48
3 月,跳不动了?>>> _beginThreadex创建多线程解读 _beginThreadex创建多线程解读 一、需要的头文件支持 #include <process.h> // for _beginthread() 需要的设置:ProjectàSetting-->C/C++-->User run-time library 选择Debug Multithreaded 或者Multithreaded。即使用: MT或MTD。 源码如下: [cpp] view plain copy #include <stdio.h> #include <string> // for STL string class #include <windows.h> // for HANDLE #include <process.h> // for _beginthread() using namespace std; class ThreadX { private : int loopStart; int loopEnd; int dispFrequency; public : string threadName; ThreadX( int startValue, int endValue, int frequency ) { loopStart = startValue; loopEnd =

Win32 多线程的创建方法,区别和联系

孤街醉人 提交于 2020-03-23 02:24:09
3 月,跳不动了?>>> Win32多线程的创建方法主要有: CreateThread() _beginthread()&&_beginthreadex() AfxBeginThread() CWinThread类 一、简介 CreateThread : Win32提供的创建线程的最基础的API ,用于在主线程上创建一个线程。返回一个HANDLE句柄(内核对象)。在内核对象使用完毕后,一般需要关闭,使用CloseHandle()函数。 _beginthread()&&_beginthreadex() : 在MSDN中可以看到一句很重要的提示,内容为“For an executable file linked with Libcmt.lib, do not call the Win32 ExitThread API; this prevents the run-time system from reclaiming allocated resources. _endthread and _endthreadex reclaim allocated thread resources and then call ExitThread.”,简单翻译就是说, 对于链接Libcmt.lib的可执行程序,不要使用Win32的线程退出函数(ExitThread) ,这会阻止运行时系统回收分配的资源

Java多线程的volatile底层实现原理

瘦欲@ 提交于 2020-03-22 23:41:36
或许你经常被问到? Volatile关键字有何作用? 实现这些作用的底层如何实现? Volatile能够保障可见性、有序性?原子性吗? 前言 我们都知道,Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令。 Volatile作用   Java语言规范第3版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。我们看下面的图来理解。2个CPU都要去操作主存中counter变量时,,他们读取主存中的变量counter到自己cpu cache中,然后操作数据。CPU1改变counter=7的操作,对CPU2是不可见的。 实现可见性 上面的例子,如果我们加上Volatile关键字,实际上底层是这么回事。 1)将当前处理器缓存行的数据写回到系统内存。 2)写回主存的操作会使在其他CPU里缓存了该内存地址的数据无效,其他CPU执行时,就需要重新从主存中获取数据。 实现禁止指令重排序 禁止指令重排序有没有什么例子?可以参考下我的另一篇文章: DCL的单例一定是线程安全的吗 Java内存模型其实是通过内存屏障(Memory Barrier)来实现的禁止指令重排序,

多线程-BlockingQueue,Array[Linked]BlockingQueue,DelayQueue,PriorityBlockingQueue,SynchronousQueue

▼魔方 西西 提交于 2020-03-22 22:25:15
阻塞场景 BlockingQueue阻塞队列,阻塞的情况主要有如下2种: 1. 当队列满了,进行入队操作阻塞 2. 当队列空了,进行出队操作阻塞 阻塞队列主要用在生产者/消费者模式中,下图展示了一个线程生产,一个线程消费的场景: BlockingQueue接口 操作 抛异常 特殊值 阻塞 超时 插入 add(o) offer(o) put(o) offer(o,timeout,unit) 删除 remove(o) poll() take() poll(timeout,unit) 1. 抛出异常:如果操作不能马上进行,则抛出异常。 2. 特殊值:如果操作不能马上进行,将会返回一个特殊的值,一般是true/false。 3. 阻塞:如果操作不能马上进行,操作会阻塞。 4. 超时:如果操作不能马上进行,操作会阻塞指定时间,如果指定时间没执行,则返回一个特殊值,一般为true/false。 不能向BlockingQueue中插入null.否则会报NullPointerException异常。 BlockingQueue子类 由以上的图片可以知道BlockingQueue具有如下的几个子类: 1. ArrayBlockingQueue 2. DelayQueue 3. LinkedBlockingQueue 4. PriorityBlockingQueue 5.

40个Java多线程问题总结

旧城冷巷雨未停 提交于 2020-03-22 20:00:51
40个问题汇总 1、多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡。所谓"知其然知其所以然","会用"只是"知其然","为什么用"才是"知其所以然",只有达到"知其然知其所以然"的程度才可以说是把一个知识点运用自如。OK,下面说说我对这个问题的看法: (1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。 单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了 。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 (2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了

Callable实现JAVA多线程

空扰寡人 提交于 2020-03-22 19:13:36
最近项目用到一个功能需要实现多线程分发任务且需要任务的返回值,之前一直都是实现Runnable接口,但里面的run方法是返回void的。后来在网上查了下JAVA1.5开始就有了Callable。 下面来看看如何倒腾下这个东西。 import java.util.concurrent.Callable; /** * @类说明 线程业务处理 * @author DavenTsang * @date 2016-11-16 * */ public class PoolTask implements Callable<String> { private String id; @Override public String call() throws Exception { return "当前线程名:" + Thread.currentThread().getName() + ":" + id; } public String getId() { return id; } public void setId(String id) { this.id = id; } } View Code 先建立一个类实现Callable接口。一下是JDK的API对Callable接口的描述: public interface Callable<V> 返回结果并且可能抛出异常的任务

Java多线程同步方法

◇◆丶佛笑我妖孽 提交于 2020-03-22 18:50:35
一、同步方法   即有 synchronized关键字修饰的方法 。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。 注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。 二、同步代码块   即有synchronized关键字修饰的语句块。 被synchronized关键字修饰的语句块会自动被加上内置锁,从而实现同步 代码如: synchronized(object){ } 注:同步是一种高开销的操作,因此应该尽量减少同步的内容。 通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。 线程在执行同步方法时是具有排它性的。 当任意一个线程进入到一个对象的任意一个 同步方法 时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。 在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。 同步块:同步块是通过锁定一个指定的对象,来对同步块中包含的代码进行同步; 而同步方法是对这个方法块里的代码进行同步,而这种情况下锁定的对象就是同步方法所属的主体对象自身。如果这个方法是静态同步方法呢