Java基础知识总结之多线程
1、基本概念
进程是程序的一次动态执行过程,是系统进行资源分配和调度运行的基本单位。
线程是进程的一个实体,它是比进程更小的的能够独立运行的基本单位。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。线程基本自己不拥有系统资源,只拥有一点在运行中必不可少的资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。它可与同属一个进程中的其他线程共享进程所拥有的全部资源。
2、引入线程与进程的目的
在OS中引入进程的目的是为了使更多的程序能够并发执行,以提高资源的利用率和系统的吞吐量。
引入线程的则是为了减少程序在并发执行时所付出的时间开销,使OS具有更好的并发性,以进一步提高资源的利用率和系统的吞吐量。
3、程序、进程与线程的关系
程序是保存在硬盘上的可执行代码,是一种静态的概念。
进程是一个程序在计算机上执行的过程,是一种动态的概念。
线程是进程的一部分,进程包含多个线程在运行。
形象的比喻:将计算机的CPU比作一座工厂,它承担了所有的计算任务。
由于单个CPU一次只能运行一个任务,所以此工厂一次只能供给一个车间。进程好比是这个车间,任何一个时刻CPU总是运行一个进程,其他进程处于非运行状态。
一个车间里有很多工人协同完成一个任务,线程好比车间里的工人,一个进程可以包括多个线程。
车间的空间是工人们共享的,这象征着一个进程的内存空间是共享的,每个其包括的线程可以使用这些共享内存。
可每间房间的大小不同,有些房间只能容纳一个人,比如厕所,里面有人的时候,其他人就不能进入。这代表一个线程使用某些共享内存的时,其他线程必须等它结束,才能使用这一块内存。
一个人防止他人进入的简单方法就是在门口加一把锁。先到的人锁上门,后来的人看见上锁就在门口排队,等锁打开在进入,这叫做“互斥锁”(Mutual exclusion,缩写 Mutex),防止多个线程同时读取某一块内存区。
具体比如: Word程序的源代码就是保存在硬盘上的可执行代码,是静态的,当启动Word程序时对于操作系统就相当于启动了一个进程,而在这个进程还有许多功能(如拼写检查)是通过一个个线程实现的。如果Word关闭了,则这些拼写检查的线程也将消失,但是如果拼写检查的线程关闭了,也并不会让Word的进程关闭。
4、任何线程一般具有5种状态:创建、就绪、运行、阻塞、终止
创建状态:新建一个线程对象可采用Thread类的构造方法来实现。
就绪状态:调用start()方法启动线程,此时线程进入线程队列排队,等待CPU的服务。
运行状态:调运线程对象的run()方法。
阻塞状态:在可执行状态下,如果调用sleep()、suspend()、wait()等方法,线程进入阻塞状态
只有当引起阻塞状态的原因消失时,线程才可以进入就绪状态。
死亡状态:调用stop()方法或run()方法执行结束时。
5、Java中的多线程
1.Java中的实现方式:
在Java中线要实现多线程操作有两种常用的手段: 一种是继承Thread类,另外一种是实现Runable接口。
通过继承Thread类实现多线程必然受到单继承的局限性的影响,并且实现Runable接口适合资源共享,所以一般来说,都是通过实现Runable接口来实现多继承。
两种方式都必须明确覆写run()方法,此方法为线程的主体。
继承Thread类要通过start()方法启动线程,而Runable接口还是要依靠Thread类的start()方法来启动线程。
2.Thread类与Runable接口的联系与区别:
联系:
1.Thread的类也是Runable接口的子类,但是Thread类中并没有完全实现Runable接口中run()方法,所以两种方式都必须明确覆写run()方法。
public class Thread extends Object implements Runnable
2.二者的操作方式类似于代理模式:
Thread类与Runable接口的子类都同时实现了Runable接口,之后将Runable的子类放到Thread类的构造器中,调用Thread类的start()方法启动线程。
区别:
1.启动线程的方式不同
2.局限性不同
3.实现Runable接口的对象可以方便的实现资源的共享,而继承Thread类则多个程序之间无法共享线程类的实例对象。
(原因:当继承Thread类实现多线程时,程序每新建一个线程都需要创建一个Thread类对象,Thread类对象的执行体run()方法是独立的,因此每个因此多个线程之间不能共享实例变量。 而以实现Runable接口的对象作为Thread对象的target,Runable实现类的run()方法仅作为Thread对象的线程执行体,而实际的的线程对象依然是Thread的实例。多个线程可以共享一个target,所以一多个线程共享一个Runable对象的实例变量。)
3.为什么启动线程时不能直接使用run()方法:
调用start()方法来启动线程,系统会把该run()当成线程的执行体来处理;但如果直接调用线程对象的run()方法,则run()将会被当做一个普通方法被执行,而不是线程的执行体。
6、死锁的概念
7、进程同步
在多道程序环境下,系统中各进程以不可预测的速度向前推进,进程的异步性对临界资源的访问会给系统造成混乱,造成了结果的不可再现性。为防止这种现象,引入进程同步的概念。
对于某些资源来说,其在同一时间只能被一个进程所占用。这些一次只能被一个进程所占用的资源就是所谓的临界资源(例如现实生活中的厕所就是一个典型的临界资源)。典型的临界资源比如物理上的打印机,或是存在硬盘或内存中被多个进程所共享的一些变量和数据等(如果这类资源不被看成临界资源加以保护,那么很有可能造成丢数据的问题)。
对于临界资源的访问,必须是互诉进行。也就是当临界资源被占用时,另一个申请临界资源的进程会被阻塞,直到其所申请的临界资源被释放。而进程内访问临界资源的代码被成为临界区。
解决同步问题的两种方式:
同步代码块
synchronized(同步对象){
...
//需要同步的代码;
}
同步方法
synchronized 关键字将一个方法声明为同步方法。
//synchronized的音标['sɪŋkrənaɪzd]
对于临界区的访问过程分为四个部分:
1.进入区:查看临界区是否可访问,如果可以访问,则转到步骤二,否则进程会被阻塞
2.临界区:在临界区做操作
3.退出区:清除临界区被占用的标志
4.剩余区:进程与临界区不相关部分的代码
8、线程池
引入原因:
系统启动一个新的线程的成本比较高,因为它涉及与操作系统交互。在这种情况下,使用线程池可以很好的提高性能。尤其是当程序中需要创建大量的生存期很短暂的线程时,更应该考虑使用线程池。
实现过程:
线程池在系统启动时即创建大量空闲的线程,程序将一个Runable对象传给线程池,线程池就会启动一个线程来执行run()方法,当run()方法结束后,该线程并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个Runable对象的run()方法。
其他优势:
线程池还可以有效的控制系统中并发进程的数量,通过设置线程池的最大线程数参数可以控制系统中并发线程数不超过此数,避免系统中包含大量并发线程导致JVM崩溃。
Java基础知识总结之多线程的更多相关文章
- Java基础知识强化之多线程笔记01:多线程基础知识(详见Android(java)笔记61~76)
1. 基础知识: Android(java)学习笔记61:多线程程序的引入 ~ Android(java)学习笔记76:多线程-定时器概述和使用
- Java基础知识回顾之五 ----- 多线程
前言 在上一篇文章中,回顾了Java的集合.而在本篇文章中主要介绍多线程的相关知识.主要介绍的知识点为线程的介绍.多线程的使用.以及在多线程中使用的一些方法. 线程和进程 线程 表示进程中负责程序执行 ...
- Java基础知识强化之多线程笔记05:Java中继承thread类 与 实现Runnable接口的区别
1. Java中线程的创建有两种方式: (1)通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中. (2)通过实现Runnable接口,实例化Thread类. 2. ...
- Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗
1. Java程序运行原理: Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...
- Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)
1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...
- Java基础知识强化之多线程笔记03:进程与线程 和 多线程的意义
1. 要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2. 什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出 ...
- Java基础知识强化之多线程笔记02:多线程之 面试题(常问)
1. 多线程有几种实现方案,分别是哪几种 ? 两种. 继承Thread类 实现Runnable接口 扩展一种:实现Callable接口.这个得和线程池结合. 2. 同步有几种方式,分别是什么? ...
- Java基础知识强化之多线程笔记07:同步、异步、阻塞式、非阻塞式 的联系与区别
1. 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.但是一旦调用返回,就必须先得到返回值了. 换句话话说,调用者主动等待这个"调用"的结果. 对于 ...
- Java基础知识强化之多线程笔记04:并行和并发 区别
1. 并发 和 并行区别 (1)并发:(单核) 并发,是在同一个cpu上同时(不是真正的同时,而是看来是同时,因为cpu要在多个程序间切换)运行多个程序. 并发是指两个任务都请求运行,而处理器只能按受 ...
随机推荐
- 小白学 Python(11):基础数据结构(元组)
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- 再谈 APISIX 高性能实践
2019 年 8 月 31 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·成都站,APISIX 主要作者王院生在活动上做了<APISIX ...
- PHPStorm 10 配置PHPUnit
PHPStorm 10 配置PHPUnit PHPUnit的安装 自己用的是Xampp,PHPUnit好像自带不好用. 不说废话: 自己看 According to official site htt ...
- WORKGROUP无法访问,您可能没有权限使用网络资源,请与这台服务器的管理员联系以....
解决方法 1.启用Guest账号 在很多情况下,为了本机系统的安全,Guest账户是被禁用的,这样就无法访问该机器的共享资源,因此必须启用Guest账户. 笔者以Windows XP系统为例进行介绍. ...
- Linux后台运行Jar方法
原文地址:http://blog.csdn.net/c1481118216 https://blog.csdn.net/c1481118216/article/details/53010963 在li ...
- 谷歌黑客语法(google hacking)让你的搜索更精准有效
Google Hacking的含义原指利用Google Google搜索引擎搜索信息来进行入侵的技术和行为: 现指利用各种搜索引擎搜索信息来进行入侵的技术和行为,但我们也可以利用这个在互联网上更加便捷 ...
- Everything可能泄漏大量电脑敏感资料
一款好用的文件搜索工具Everything被批露出现重大问题: Everything可以打开http服务,在没有加密的情况下任何外网电脑都可以连接的. 因此,Everything可能泄漏大量电脑敏感资 ...
- Python实战练习——打印日历教程
很长一段时间没有接触过C语言了,想来做这一行当已经有三两年了. 今天突然想起来以前用C语言在VC6上写代码的日子,想了想以前的一些实战练习. 所以今天打算用Python来写一个C语言以前练习的题目-日 ...
- 暑期集训20190726 跳动(skip)
[题目描述] 福州三中的操场上有着数不尽的跳动的小朋友. 当然善于思考的你总能从中发掘出不一样的问题 福州三中的跑道是一个n个格子围成的圆形,从0~n-1编号,有m个同学,第i个同学步长为a[i], ...
- IDEA复制多行及对多行代码上下左右移动
复制: 复制一行可不需要选中 多行需要选中 mac:command+D window:ctrl+D 移动: 选中代码 左移:tab+shift 右移:tab 上移:shift+alt+向上方向键 下移 ...