线程

为什么要同步

我只是一个虾纸丫 提交于 2020-03-31 08:22:11
8.1、为什么要同步 线程之间是合作关系。既然是合作,那就要由某种约定的规则,否则合作就会出现问题。 例子1 : 有两个线程同时运行,第一个线程在执行了一些操作后想检查当前的错误状态errno,但在其做检查之前,线程2却修改了errno。这样,当第一个线程再次获得控制权后,检查结果将是线程2改写过的errno,而这是不正确的。 线程1 线程2 。。。。。 。。。。 读errno变量 。。。。 。。。。 写errno变量 从读操作返回 。。。。 检查errno值 。。。。 一个进程的两个线程因为操作不同步而造成线程1运行错误。 之所以出现上述问题,是基于两个原因: l errno是线程之间共享的全局变量 l 线程之间的相对执行顺序是不确定的 因此,要解决上述问题有两个办法,即分别消除上述两个原因。消除第1个原因的办法就是限制全局变量,给每个线程一个私有的errno变量。事实上,如果可以将所有的资源都私有化,让线程之间不共享,那么这种问题就不复存在。 但问题是,如果所有资源都不共享,那么还有必要发明线程吗?甚至也没有必要发明进程了。因为这样就违背了进程和线程设计的初衷:共享资源、提高资源利用率。因此,这种解决办法是不切实际的。 那剩下的办法就是消除第2个原因,即让线程之间的相对执行顺序在需要的时候可以确定。 例子2 : 有两个线程A和B,分别执行指令x=1和x=2,即 线程A:x=1;

day09 并发编程

允我心安 提交于 2020-03-31 08:06:11
一. 目录   1.进程的概念和两种创建方式   2.多进程爬虫   3.守护进程   4.进程队列   5.进程队列简单应用(实现数据共享)   6.线程的两种创建方式   7.线程和进程的效率对比   8.线程共享统一进程的数据   9.死锁现象   10.线程队列的三种应用   11.多线程执行计算密集型任务   12. 线程池和进程池   13. 回调函数   14.守护线程   15. 协程   16.GlL 全局解释器锁 二. 内容 一.进程的概念和两种创建方式 专业词描述: 操作系统的两大作用 1.把硬件丑陋复杂的接口隐藏起来,为应用程序提供良好的接口 2.管理,调度进程,并且把进程之间对硬件的竞争变的有序化多道技术: 1.产生背景:为了实现单cpu下的并发效果 2.分为两个部分 1.空间上的复用(必须实现硬件层面的隔离) 2.时间上的复用(复用的是cpu的时间片) 什么时候切换? 1.正在执行的任务遇到阻塞 2.正在执行的任务运行时间过程(系统控制的)进程:正在运行的一个过程,一个任务,由操作系统负责调度,由cpu负责 执行程序:程序员写的代码并发:伪并行,单核+多道并行:只有多核才能实现真正的并行同步:一个进程在执行某个任务时,另外一个进程必须等待其执行完毕才能往下走异步:一个进程在执行某个任务时,另外一个进程无须等待其执行完毕,继续往下走进程的创建: 1

java中volatile关键字的含义

人盡茶涼 提交于 2020-03-31 08:05:46
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。 synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法 或者 代码块。 volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 下面看一个例子,我们实现一个计数器,每次线程启动的时候,会调用计数器inc方法,对计数器进行加一 执行环境——jdk版本:jdk1.6.0_31 ,内存 :3G cpu:x86 2.4G public class Counter { public static int count = 0; public static void inc() { //这里延迟1毫秒,使得结果明显 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public

JAVA 几种引用类型学习

ⅰ亾dé卋堺 提交于 2020-03-31 08:02:10
1、对象的强、软、弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及(reachable)状态,程序才能使用它。从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。 图1为对象应用类层次 1)强引用(StrongReference) 强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java 虚拟机 宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 2)软引用(SoftReference) 如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存(下文给出示例)。 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。 3) 弱引用(WeakReference) 弱引用与软引用的区别在于:弱引用的对象拥有更短暂的生命周期

Android中后台线程如何与UI线程交互

半世苍凉 提交于 2020-03-31 06:43:35
我想关于这个话题已经有很多前辈讨论过了。今天算是一次学习总结吧。 在android的设计思想中,为了确保用户顺滑的操作体验。一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务。因此我们必须要重新开启一个后台线程运行这些任务。然而,往往这些任务最终又会直接或者间接的需要访问和控制UI控件。例如访问网络获取数据,然后需要将这些数据处理显示出来。就出现了上面所说的情况。原本这是在正常不过的现象了,但是android规定除了UI线程外,其他线程都不可以对那些UI控件访问和操控。为了解决这个问题,于是就引出了我们今天的话题。Android中后台线程如何与UI线程交互。 据我所知android提供了以下几种方法,用于实现后台线程与UI线程的交互。 1、handler 2、Activity.runOnUIThread(Runnable) 3、View.Post(Runnable) 4、View.PostDelayed(Runnabe,long) 5、AsyncTask 方法一:handler handler是android中专门用来在线程之间传递信息类的工具。 要讲明handler的用法非常简单,但是我在这里会少许深入的讲一下handler的运行机制。 为了能够让handler在线程间传递消息,我们还需要用到几个类。他们是looper,messageQueue,message。

[STAThread]的含义

ε祈祈猫儿з 提交于 2020-03-31 06:42:02
Posted on 2007-07-07 10:06 桦林 阅读( 33100) 评论( 10) 编辑 收藏 [STAThread] STAThread:Single Thread Apartment Thread.(单一线程单元线程) []是用来表示Attributes; [STAThread] 是一种线程模型,用在程序的入口方法上(在C#和VB.NET里是Main()方法),来指定当前线程的ApartmentState 是STA。用在其他方法上不产生影响。在aspx页面上可以使用 AspCompat = "true" 来达到同样的效果。这个属性只在 Com Interop 有用,如果全部是 managed code 则无用。简单的说法:[STAThread]指示应用程序的默认线程模型是单线程单元 (STA)。启动线程模型可设置为单线程单元或多线程单元。如果未对其进行设置,则该线程不被初始化。也就是说如果你用的.NET Framework,并且没有使用COM Interop,一般不需要这个Attribute。其它的还有MTA(多线程套间)、Free Thread(自由线程)。 [STAThread] attribute指示应用程序的 COM 线程模型是单线程单元。 而于此对应的多线程单元则是 [MTAThread] (多线程单元线程) COM 线程模型只适用于使用 COM

Java NIO SocketChannel+Buffer+Selector 详解(含多人聊天室实例)

◇◆丶佛笑我妖孽 提交于 2020-03-31 05:42:17
一、Java NIO 的核心组件 Java NIO的核心组件包括: Channel(通道),Buffer(缓冲区),Selector(选择器) ,其中Channel和Buffer比较好理解 简单来说 NIO是面向通道和缓冲区的 ,意思就是: 数据总是从通道中读到buffer缓冲区内,或者从buffer写入到通道中。 关于Channel 和 Buffer的详细讲解请看: Java NIO 教程 二、Java NIO Selector 1. Selector简介 选择器提供选择执行已经就绪的任务的能力.从底层来看,Selector提供了询问通道是否已经准备好执行每个I/O操作的能力。Selector 允许单线程处理多个Channel。仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道,这样会大量的减少线程之间上下文切换的开销。 在开始之前,需要回顾一下Selector、SelectableChannel和SelectionKey: 选择器(Selector) Selector选择器类管理着一个被注册的通道集合的信息和它们的就绪状态。通道是和选择器一起被注册的,并且使用选择器来更新通道的就绪状态。当这么做的时候,可以选择将被激发的线程挂起,直到有就绪的的通道。 可选择通道(SelectableChannel)

python学习——进程

两盒软妹~` 提交于 2020-03-31 02:56:48
1. 操作系统/应用程序 a. 硬件 - 硬盘 - CPU - 主板 - 显卡 - 内存 - 电源 ... b. 装系统(软件) - 系统就是一个由程序员写出来软件,该软件用于控制计算机的硬件, 让他们之间进行相互配合。 c. 安软件(安装应用程序) - QQ - 百度云 - pycharm ... 2. 并发和并行 并发,伪,由于一个人执行速度特别快,人感觉不到停顿。 并行,真,创建10个人同时操作。3. 线程、进程 a. 单进程、单线程的应用程序 print('666') b. 到底什么是线程?什么是进程? Python自己没有这玩意,Python中调用的操作系统的线程和进程。 c. 单进程、多线程的应用程序 代码: import threading print('666') def func(arg): print(arg) t = threading.Thread(target=func) t.start() print('end') 一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以创建多个线程(默认一个)。 d. 故事: Alex甄嬛西游传 总结: 1. 操作系统帮助开发者操作硬件。 2. 程序员写好代码在操作系统上运行(依赖解释器)。 任务特别多的情况: 3. 以前的你,写代码: import threading import requests

Android学习记录:线程

北慕城南 提交于 2020-03-31 02:16:20
在Java中,线程的建立方法如下。 新建一个类,接口Runnable,重载 run方法 import javax.swing.JTextField; public class test implements Runnable{ @Override public void run() { } } 在需要开始这个线程的地方,这样创建线程 private Thread th; test te = new test(); th = new Thread(te); th.start(); Java中调用线程的时候,可以直接访问JFrame上的组件,并更改其值,但是在安卓中,如果一个子线程涉及到UI更新,Android主线的线程是不安全的。更新UI只能在主线程中更新。 所以要把Message通过handler来send,然后利用callback来接收。 新建类,接口Callback 重载的handleMessage中就是对从子线程中传入的Message做处理。 import android.os.Handler.Callback; import android.os.Message; import android.widget.TextView; public class CB implements Callback{ private TextView tv; public TextView