一、内容要点
1. 线程的基本概念
2. 线程的创建和启动
3. 线程的调度和优先级
4. 线程的状态控制
5. 线程同步
6.名词解释
7.线程中的常用方法
二、基础模块
1 . 线程的基本概念
理解线程首先要了解如下几个概念
(1)进程: 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。事例:比如在Windows系统中, 一个运行的exe就是一个进程。
(2)线程: 线程是一个程序内部的顺序控制流。线程可以看成是轻量级进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,线程切换开销小。
事例:如qq.exe中发送文件,上传文件等线程。
(3)多进程:在操作系统中能同时运行多个任务(程序)
(4)多线程:在同一个应用程序中有多个顺序流同时执行。
2. 线程的创建和启动
java中的线程:java的线程是通过java.lang.Thread类来实现的,jvm启动时会有一个主方法main所定义的线程,可以通过创建 Thread的实例来创建新的线程,
通过线程Thread类的start方法来启动一个线程。
创建新线程的方式:
(1). 定义线程类实现Runnable接口
(2). 继承Thread类重写其run方法
线程的启动:在线程的Thread对象上调用start()方法,注意不是run()或者别的方法
Thread 类有个 registerNatives 本地方法,该方法主要的作用就是注册一些本地方法供 Thread 类使用,如 start0(),stop0() 等等,
可以说,所有操作本地线程的本地方法都是由它注册的 . 这个方法放在一个 static 语句块中,这就表明,当该类被加载到 JVM 中的时候,
它就会被调用,进而注册相应的本地方法
private static native void registerNatives(); static { registerNatives(); }
3. 线程的调度和优先级
有两种调度模型:分时调度模型和抢占式调度模型。
分时调度模型:分时调度模型是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片这个也比较好理解。
抢占式调度模:java虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,
使其占用CPU。处于运行状态的线程会一直运行,直至它不得不放弃CPU
线程优先级:
(1)MIN_PRIORITY 1
(2)NORM_PRIORITY 5
(3)MAX_PRIORITY 10
可以通过线程类的setPriority方法修改线程执行的优先级
注意:高优先级的线程不一定先于低优先级的线程执行,只是高优先级的线程比低优先级的线程得到执行的机会更高些
4. 线程的状态控制
线程的状态如下:
(1)新建状态(创建);
(2)就绪状态;
(3)运行状态;
(4)阻塞状态;
(5)死亡状态(终止)
状态之间的转换如下图:
5. 线程同步
(1)为何要使用同步
java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之 间产生冲突,
因此加入同步锁以避免在 该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。
在java语言中引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象都对应一个可称为“互斥锁”的标记,这个标记保证在任何时刻,
只能有一个线程访问该对象,关键字synchronized来与对象的互斥锁联系,当某个对象synchronized时,表明该对象在任意一时刻只能有一个线程来访问。
synchronized还可以修饰方法,表示整个方法为同步方法。
(2)synchronized关键字的作用域:
(a):同步方法:是某个对象实例内,synchronized aMethod{},synchronized关键字修饰的方法可以防止多个线程同时访问这个对象的synchronized方法
(如果一 个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。
这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
(b)静态方法:是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。
它可以对类的所有对象实例起作用。
(c) 同步代码块:除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
用法是: synchronized(this){/*区块*/},它的作用域是当前对象
注意:synchronized关键字是不能继承的,也就是说,基类的方法synchronized aMethod(){} 在继承类中并不自动是synchronized aMethod(){},
而是变成了aMethod(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
6.名称解释:
(1).主线程:JVM调用程序main()所产生的线程。
(2).当前线程:一般指通过Thread.currentThread()来获取的线程
(3).后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。
用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束
(4).前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起,就像傀儡和幕后操纵者一样的关系。
可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程(守护线程)
(5)可重入锁:也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。
在JAVA环境下 ReentrantLock 和synchronized都是可重入锁
7.线程类中的常用方法:
(1)sleep(): 强迫一个线程睡眠N毫秒。
(2)isAlive(): 判断一个线程是否存活。
(3)join(): 等待线程终止。
(4)activeCount(): 程序中活跃的线程数。
(5)enumerate(): 枚举程序中的线程。
(6)currentThread(): 得到当前线程。
(7)isDaemon(): 一个线程是否为守护线程。
(8)setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
(9)setName(): 为线程设置一个名称。
(10)wait(): 强迫一个线程等待。
(11)notify(): 通知一个线程继续运行。
(12)setPriority(): 设置一个线程的优先级
三、高级进阶
相关知识点(待续)
1. 操作系统的相关概念
2. 线程间通信
3. 内核级线程与用户级线程的概念
4. 线程组的相关知识
5. concurrent包中常用类简介
作者:南唐三少
出处:http://www.cnblogs.com/nantang
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我们最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文链接,否则保留追究法律责任的权利。