进程是处于运行过程中的程序,在内存中有一段独立空间;线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程;操作系统可以同时执行多个任务,每个任务就是进程;就成可以同时执行多个任务,每个任务就是线程。

一. 线程的创建和启动

  • 继承Thread类创建线程类
  • 实现Runnable接口创建线程类
  • 使用Callable和Future创建线程

二. 线程的生命周期

分为新建、就绪、运行、阻塞、死亡五个状态
线程的生命周期

三. 线程的控制

  • join线程:让一个线程等待另一个线程完成的方法——join()方法
  • 后台线程:在后台运行的,为其他线程提供服务
  • 线程睡眠:让当前正在执行的线程暂停一段时间,并进入阻塞状态,可通过调用Thread类的静态Sleep()方法实现
  • 线程让步:让当前正在执行的线程暂停,并转入就绪状态,可以通过调用Thread类的静态yield()方法实现
  • 改变线程优先级:每个线程执行时都具有一定的优先级,优先级高的线程获得较多的执行机会,而优先级低的线程则获得较少执行机会,可通过Thread类的SetPriority()方法来设置

四. 线程同步

  1. 当时用多个线程来访问同一个数据时,很容易“偶然”出现线程安全问题
  2. 为解决这个问题,Java的多线程支持引入同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块
  3. 与同步代码块对应,Java的多线程安全支持还提供了同步方法,同步方法就是使用Synchronized关键字来修饰某个方法

同步锁

通过显示定义同步锁对象来实现同步,在这种机制下,同步锁由Lock对象充当。

死锁

当两个线程相互等待对方释放同步监视器时就会发生死锁。一旦发生死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

五. 线程通信

当线程在系统内运行时,线程的调度就有一定的透明性,程序通常无法准确控制线程的轮换执行,但Java也提供了一些机制来保证线程协调运行。

综合实例:创建两个线程,一个线程打印1-52,另一个线程打印字母A-Z ,实现输出12A34B56C78D910E1112F1314G1516H1718I。。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.lousen.duoxiancheng;
/**
* 多线程
* 用java写两个线程,一个线程打印1-52,另一个线程打印字母A-Z
* 运行结果:12A34B56C78D910E1112F1314G1516H1718I。。。。
* */
public class NotifyWait {
public static void main(String[] args){
Object obj = new Object();
//启动两个线程
Thread1 t1 = new Thread1(obj);
Thread2 t2 = new Thread2(obj);
t1.start();
t2.start();
}
}
/*创建线程1*/
class Thread1 extends Thread {
private Object obj;
public Thread1(Object obj){
this.obj = obj;
}
//重写run方法
public void run(){
//加锁
synchronized(obj){
//打印1-52
for(int i = 1; i < 53; i++ ){
System.out.print(i);
if(i % 2 == 0){
//唤醒其他线程
obj.notifyAll();
try {
obj.wait(); //释放对同步监视器的锁定
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
/*创建线程2*/
class Thread2 extends Thread{
Object obj = new Object();
public Thread2(Object obj){
this.obj = obj;
}
//重写run方法
public void run(){
//加锁
synchronized(obj){
//打印A-Z
for(int i = 0; i < 26; i++){
System.out.print((char)('A'+i));
obj.notifyAll(); //唤醒其他线程
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

最后更新: 2020年07月27日 03:51

原始链接: https://www.lousenjay.top/2018/02/04/多线程学习笔记/