线程阻塞

多线程学习

廉价感情. 提交于 2020-03-23 14:45:46
1、线程概述    进程:运行在自己的地址空间之内的自包容的程序,是一个动态执行的过程。 比如我打开记事本写一个.txt文件这个过程是一个进程;打开eclipse写一个程序这个过程是一个进程;运行这个程序也是一个进程; 人跑50m短跑这个过程也可以说是一个进程。    线程:是比进程更小的执行单位,是一个个独立的子任务,一个线程就是在进程中的一个的单一的顺序控制流。 比如运行一个.java文件时,主线程就是立刻启动运行;50m短跑的一个同学是一个线程;比赛100m x 4 这个过程是一个进程,这个进程给参赛的4位同学都分配了任务(每位同学跑100m)。   从上我们可以看到 进程之间相互隔开,互不影响,彼此不干涉的 ;而 同一个进程之间的线程之间时共享资源的 (接力赛的接力棒), 线程之间的执行顺序也是不确定的 ,在这个100 x 4 比赛中,每个同学跑第几棒是不确定的,顺序是由leader(这里我们假设是班主任)来确定的,此时班主任担任的就是一个CPU在分配资源的角色。    多线程:顾名思义就是一个进程中有多个线程。 java的线程机制是抢占式,这表示调度机制会周期性地中断线程,讲上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都分配到数量合理的事件驱动它的任务。    注意: 多线程是不能提高运行效率的,相反的在单处理器上还会降低一些运行效率

C#多线程学习

混江龙づ霸主 提交于 2020-03-23 14:44:37
一、线程的定义    进程(Process) 是Windows系统中的一个基本概念,它 包含着一个运行程序所需要的资源 。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。 进程可以理解为一个程序的基本边界 。    线程(Thread) 是 进程中的基本执行单元 ,在 进程入口执行的第一个线程被视为这个进程的主线程 。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。    多线程 ,在单CPU系统的一个单位时间( time slice)内, CPU只能运行单个线程 , 运行顺序取决于线程的优先级别 。如果在单位时间内线程未能完成执行,系统就会把线程的状态信息保存到线程的本地存储器(TLS)中,以便下次执行时恢复执行。而多线程只是系统带来的一个假象,它在多个单位时间内进行多个线程的切换。因为切换频密而且单位时间非常短暂,所以多线程可以被视作同时运行。   

AutoResetEvent 详解

[亡魂溺海] 提交于 2020-03-23 14:39:28
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程 通过调用 Set 发出资源可用的信号。 调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。 可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true ;否则为 false 。 通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号, 等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。下面我们来举一个例子:我去书店买书,当我选中一本书后我会去收费处付钱, 付好钱后再去仓库取书。这个顺序不能颠倒,我作为主线程,收费处和仓库做两个辅助线程,代码如下: using System; using System.Linq; using System

java之AQS和显式锁

China☆狼群 提交于 2020-03-23 09:46:55
  本次内容主要介绍AQS、AQS的设计及使用、 ReentrantLock、 ReentrantReadWriteLock以及手写一个可重入独占锁 1、什么是AQS ?    A QS,队列同步器AbstractQueuedSynchronizer的简写,JDK1.5引入的, 是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。AQS的作者Doug Lea大师期望它能够成为实现大部分同步需求的基础。 2、AQS的设计及其作用    AbstractQueuedSynchronizer是一个抽象类,先看一下其类图。   AQS中里有一个volatile修饰int型的state来代表同步状态,使用同步器提供的3个方法(getState()、setState(int newState)和compareAndSetState(int expect,int update))来改变状态,因为它们能够保证状态的改变是安全的。   AQS使用的是模板方法模式,主要使用方式是继承,且通常将子类推荐定义为静态内部类,子类通过继承AQS并实现它的抽象方法来管理同步状态。AQS自身没有实现任何同步接口,它仅仅是定义了若干同步状态获取和释放的方法来供自定义同步组件使用,同步器既可以支持独占式地获取同步状态

wait、notify、sleep、interrupt对比分析

▼魔方 西西 提交于 2020-03-23 09:44:21
copy from : http://gityuan.com/2016/01/03/java-thread-wait-sleep/ 对比分析Java中的各个线程相关的wait()、notify()、sleep()、interrupt()方法 方法简述 Thread类 sleep:暂停当前正在执行的线程;(类方法) yield:暂停当前正在执行的线程,并执行其他线程;(类方法) join:等待该线程终止; interrupt:中断该线程,当线程调用wait(),sleep(),join()或I/O操作时,将收到InterruptedException或 ClosedByInterruptException; Object类 wait:暂停当前正在执行的线程,直到调用notify()或notifyAll()方法或超时,退出等待状态; notify:唤醒在该对象上等待的一个线程; notifyAll:唤醒在该对象上等待的所有线程; 详细分析 sleep VS wait sleep()和wait()方法都是暂停当前正在执行的线程,出让CPU资源。 方法 所属类 方法类型 锁 解除方法 场景 用途 sleep Thread 静态方法 不释放锁 timeout,interrupt 无限制 线程内的控制 wait Object 非静态方法 释放锁 timeout,notify,interrupt

延迟任务的实现总结

早过忘川 提交于 2020-03-23 08:48:25
上一篇 写了使用RabbitMQ来实现延迟任务的实现,其实实现延迟任务的方式有很多,各有利弊,有单机和分布式的。在这里做一个总结,在遇到这类问题的时候希望给大家一个参考和思路。 延迟任务有别于定式任务,定式任务往往是固定周期的,有明确的触发时间。而延迟任务一般没有固定的开始时间,它常常是由一个事件触发的,而在这个事件触发之后的一段时间内触发另一个事件。延迟任务相关的业务场景如下: 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时。 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单。 下面我们来探讨一些方案,其实这些方案没有好坏之分,和系统架构一样,只有最适合。对于数据量较小的情况下,任意一种方案都可行,考虑的是简单明了和开发速度,尽量避免把系统搞复杂了。而对于数据量较大的情况下,就需要有一些选择,并不是所有的方案都适合了。 1. 数据库轮询 这是比较常见的一种方式,所有的订单或者所有的命令一般都会存储在数据库中。我们会起一个线程去扫数据库或者一个数据库定时Job,找到那些超时的数据,直接更新状态,或者拿出来执行一些操作。这种方式很简单,不会引入其他的技术,开发周期短。 如果数据量比较大,千万级甚至更多,插入频率很高的话,上面的方式在性能上会出现一些问题,查找和更新对会占用很多时间,轮询频率高的话甚至会影响数据入库

python并发编程之多进程理论部分

本小妞迷上赌 提交于 2020-03-23 05:41:13
内容概要 操作系统介绍 进程 线程 协程 二. 进程 python并发编程之多进程理论部分 在python程序中的进程操作   运行中的程序就是一个进程。所有的进程都是通过它的父进程来创建的。因此,运行起来的python程序也是一个进程,那么我们也可以在程序中再创建子进程。多个进程可以实现并发效果,也就是说,当我们的程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快。创建进程这个功能需要借助python中强大的模块。 multiprocess模块   multiprocess不是一个模块而是python中一个操作、管理进程的包。 这个包中几乎包含了和进程有关的所有子模块。大致分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享。 multiprocess.process模块 process模块介绍   process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。 class Process(object): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): self.name = '' self.daemon = False self.authkey = None self.exitcode = None self.ident = 0

Java NIO系列教程(六) Selector

吃可爱长大的小学妹 提交于 2020-03-23 05:11:11
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。 下面是本文所涉及到的主题列表: 为什么使用Selector? Selector的创建 向Selector注册通道 SelectionKey 通过Selector选择通道 wakeUp() close() 完整的示例 为什么使用Selector? 仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道。对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源(如内存)。因此,使用的线程越少越好。 但是,需要记住,现代的操作系统和CPU在多任务方面表现的越来越好,所以多线程的开销随着时间的推移,变得越来越小了。实际上,如果一个CPU有多个内核,不使用多任务可能是在浪费CPU能力。不管怎么说,关于那种设计的讨论应该放在另一篇不同的文章中。在这里,只要知道使用Selector能够处理多个通道就足够了。 下面是单线程使用一个Selector处理3个channel的示例图: Selector的创建 通过调用Selector.open()方法创建一个Selector,如下: Selector selector =

多线程(三):线程安全

喜夏-厌秋 提交于 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

线程池python

跟風遠走 提交于 2020-03-23 00:46:45
为什么需要线程池   目前的大多数网络服务器,包括Web服务器、Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短。   传统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行任务。任务执行完毕后,线程退出,这就是是“ 即时创建, 即时销毁 ”的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是 如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器将处于不停的创建线程,销毁线程的状态 。   我们将传统方案中的线程执行过程分为三个过程:T1、T2、T3:   T1:线程创建时间   T2:线程执行时间,包括线程的同步等时间   T3:线程销毁时间   那么我们可以看出,线程本身的开销所占的比例为(T1+T3) / (T1+T2+T3)。如果线程执行的时间很短的话,这比开销可能占到20%-50%左右。如果任务执行时间很频繁的话,这笔开销将是不可忽略的。   除此之外,线程池能够减少创建的线程个数。通常线程池所允许的并发线程是有上界的,如果同时需要并发的线程数超过上界,那么一部分线程将会等待。而传统方案中,如果同时请求数目为2000,那么最坏情况下,系统可能需要产生2000个线程。 尽管这不是一个很大的数目,但是也有部分机器可能达不到这种要求。