温故知新 线程

项目中常会用到定时器任务调度(线程知识)

本人原电子系后转行到软件,所以对计算机原理方面颇感兴趣!

谈线程钱必须知道进程,CPU调用程序,以进程体系,轮询。

时间片(CPU定轮询周期),每个进程周期一样,(如上图)当前执行进程1指令。执行到一半,操作系统OS (管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石)给它分配时间到了,收回。

它把这个进程挂起,暂时保存起来。OS就去按顺序遍历,执行进程2,...........直到执行到进程8的时间片用完了,挂起进程8。接着执行进程1,恢复现场,接着执行。

注意:进程调度,程序之间可以切换。cpu执行太快会给人错觉误以为程序都是并行(同时运行);其实cpu定轮询周期(时间片),每个进程运行/执行的时间固定,当时间到了进程仍没执行完,当前进程挂起,执行下一条进程(直到进程8结束),当OS再次执行时,又回到进程1,恢复现场,接着执行;

知道了进程后,开始谈谈线程了:

一个进程可包含多个线程,也就是线程是OS(操作系统)可以执行的最小单位;(查服务器主机几核几线程  【cmd->wmic->cpu get *】查看对应的NumberOfCores和NumberOfLogicalProcessors )

线程数=Ncpu/(1-阻塞系数)

Ncpu---CPU数     阻尼系数---(0到1之间)

线程数大于CPU核数(并行):

并行:多核情况下,各自CPU执行各自内容,可以同时执行;

并发:多核情况下,某一个核中执行个线程,此时就产生并发,分片执行,轮着顺序执行。也称为交替执行。

上图摘自网络:(一图胜千文)

JVM在多线程时,访问公用变量(堆、方法区。。。)的每个线程是自由的,但有线程存在私有变量会有私有的栈来供他存放(保证了线程间隔离的安全)

切记创建线程数非常多,可能造成内存溢出;--------因为每个线程要分配单独内存空间,直接占用。(可以理解为独食大王,宁占着不让位)

多线程创建方式:

1) 继承Thread

2) 实现Runnable,无返回值,无异常接收

3) 实现Callable,返回值,接收异常,多了一些对象 Future、FutureTask

4) 线程池

多线程状态:

1,新建new;调用start()方法,注:所有的线程都从start开始(仅一次且由OS决定

2,可运行态Runnable; 1, 当时间片用完,运行态会调用 yiled()转到可运行态;注:【yiled() 会强制退回到就绪状态,代码主动调用。主动把CPU让出来,让其他线程去执行。俗称挂起】   ,2,当OS选中时,会从可运行态转运行态;

3,运行态Running;Run方法执行完成,线程就结束,释放资源。(切记不要本线程调用---那将毫无意义)

4,阻塞态blocked;  对于阻塞态和运行态,可运行态 典型的稳定三角关系:

运行态变阻塞:

sleep()   【它会把CPU让出来,先阻塞等待(我先睡会你们继续)】醒来后转为可运行态;

join() 【运行快的所有线程都等待,只到最慢那个线程执行完成,(有福同享,有难共当)】

wait()   【当前线程优先占用,其他线程停止,(有肉我先吃)】 当调用interrupt()或notify()或notifyAll()被唤醒后仍处于阻塞态,可转为可运行态;’

加锁Synchronized 【关键字,同步,同步锁,代码块,多行代码被加锁】 原子性操作,其他线程无法执行(特别注意CPU不是立即执行,而是轮询到它在执行。),切记加锁范围越小越好!

阻塞态变可运行态:获得锁   sleep时间到了

5,终止态Dead ;run()结束

特别要重视线程池:

通俗讲就是线程的集合,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。(可以理解为 孟尝君食客三千待用);

作用:防止多线程运行,系统不断闭合新线程,系统资源不断消耗,线程切换频繁,导致系统崩溃 (蓝屏的真好喝!)

线程池可参见博客大神闯天创世纪的博文:https://www.cnblogs.com/jiawen010/p/11855768.html

多线程并发在项目中常见安全问题:

甩卖问题:

多个窗口卖固定的货:      m个窗口   卖n件货

线程m个   甩卖过程   n递减(假设没退换,卖出责任不究)

其实主要是当n=1时问题出来了,要解决超卖现象:解决办法-------加锁(执行结束锁就释放),在加锁范围内不能高并发,只能一个对象去使用。

在商品秒杀系统时,有条件有选择的在读操作上加锁,库存小于一个量时开始加锁,让购买者排队;用一个队列缓存,将多线程变为单线程读写;

原文地址:https://www.cnblogs.com/pureray-hui/p/12560513.html

时间: 2024-11-04 09:27:55

温故知新 线程的相关文章

各科基础详实

一. Java基础部分 1. JAVA的基本数据类型有哪些 ?  String 是不是基本数据类型 ? 2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 3. Java有没有goto? 7 4. 说说&和&&的区别. 7 5. 在JAVA中如何跳出当前的多重嵌套循环? 7 6. switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 8 7. short s1 = 1; s1 = s1 + 1;有什么

Android Fragment使用(一) 基础篇 温故知新

Fragment使用的基本知识点总结, 包括Fragment的添加, 参数传递和通信, 生命周期和各种操作. Fragment使用基础 Fragment添加 方法一: 布局里的标签 标识符: tag, id, 如果都没有, container的id将会被使用. 方法二: 动态添加 动态添加利用了一个transaction: FragmentManager fragmentManager = getFragmentManager(); Fragment fragment = fragmentMan

【温故知新】C#委托delegate

在c#的学习过程中,学到委托与事件总会迷糊一段时间,迷糊过后自然而就似懂非懂了~,所以最近我打算把以前所学的迷糊过的知识总结,温故知新,总结记录下来. 首先,我们来看一下msdn对委托的定义: delegate 关键字用于声明可用来封装命名方法的引用类型.委托大致类似于 C++ 中的函数指针:但是,委托是类型安全和可靠的. delegate 可让您传递一个函数作为参数.委托的类型安全要求作为 delegate 传递的函数具有与 delegate 声明相同的签名. 委托是事件的基础. 我们都知道,

安卓开发(Java)中关于final关键字与线程安全性

前言 学习新知识固然重要,但是时常往回看看,温故知新是很必要的.回顾一下线程安全性和final关键字. 正文 从Java 5开始,final keyword一个特殊用法是在并发库中一个非常重要且经常被忽视的武器.实质上,可以使用final来确保在构造对象时,访问该对象的另一个线程不会看到处于部分构造状态的对象,否则可能会发生这种情况.这是因为当作为对象变量的一个属性时,final作为其定义的一部分具有以下重要特征: 当构造函数退出时,final keyword的值保证对访问构造对象的其他线程可见

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 1 2 3 4 5 6 7 new Thread(new

201709018工作日记--线程状态的转换

先来张图: 线程在一定条件下,状态会发生变化: 1.新建状态(New):新创建了一个线程对象 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权. 3.运行状态(Running):就绪状态的线程获取了CPU,执行程序代码. 4.阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行.直到线程进入就绪状态,才有机会转到运行状态.阻塞的情况分三种:   (一).等

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

线程的控制和线程池

一.WaitHandle: ”.Net 中提供了一些线程间更自由通讯的工具,他们提供了通过"信号"进行通讯的机制 可以通过ManualResetEvent,AutoResetEvent(他是在开门并且一个 WaitOne 通过后自动关门)来进行线程间的通讯 waitOne:    等待开门 Set:           开门 Reset:       关门 static void Main(string[] args) { ManualResetEvent mre = new Manu

内存池、进程池、线程池

首先介绍一个概念"池化技术 ".池化技术 一言以蔽之就是:提前保存大量的资源,以备不时之需以及重复使用. 池化技术应用广泛,如内存池,线程池,连接池等等.内存池相关的内容,建议看看Apache.Nginx等开源web服务器的内存池实现. 起因:由于在实际应用当中,分配内存.创建进程.线程都会设计到一些系统调用,系统调用需要导致程序从用户态切换到内核态,是非常耗时的操作.           因此,当程序中需要频繁的进行内存申请释放,进程.线程创建销毁等操作时,通常会使用内存池.进程池.