一.进程
- 程序是一个“静态”的概念,当程序被CPU调用运行时,就被赋予了生命,称为“进
程”(也叫“任务”) - 多任务的操作系统:分CPU时间片,宏观并行,微观串行
二.线程
概念
1)单个进程里,并发的一个单一的顺序执行流程
2)分CPU时间片,每一个时间片只执行一个线程(宏观并行,微观串行)组成
1)CPU :需要分配时间片(Linux:5-800微秒 Windows:5-60微秒)
2)数据 :堆空间共享(对象),栈空间独立(引用)
线程是一个“轻量级的进程”(线程交换数据比较容易)
3)代码
I. 继承Thread类 --- extends Thread
A. 覆盖run方法(线程体)
B. 创建对象 Thread t = new MyThread();
C. 启动线程 t.start()
II. 实现Runnable接口 --- implements Runnable
A. 覆盖run方法(指定线程执行代码)
B. 创建接口对象 Runnable r = new MyThread(); 目标对象
C. 创建线程对象 Thread t = new Thread( r ) ;
D. 启动线程 t.start()
3.Thread里的特殊方法:
1)sleep(long) --- 休眠
2)yield() --- 放弃cpu,回到可循运行状态
- join() --- 邀请其他线程加入到当前线程的运行中来,需要等到加入的线程执行结
束,当前线程才会继续执行。
- 线程同步
1)线程不安全:当多个线程并发访问“临界资源”时,如果“原子操作”被破坏,会
导致数据不一致的情况。
临界资源:共享资源(同一对象),为了安全保证同一原子操作只能有一个线程访问
原子操作:不可分割的多个步骤,视为一个整体,这组代码的结构顺序不能被打乱
2)互斥锁标记:每个对象都有一个“互斥锁”标记,用来分配给线程
3)锁池:每个对象天生都有一块内存空间(锁池),用来存放等待它锁标记的线程
4)同步方式:
A. 同步代码块【优选】
B. 同步方法
- 死锁
1)同步越多越好? --- 不好
A. 效率低,将并行改为串行
B. 容易引起死锁现象
2)死锁现象
A. 一个线程可以同时拥有多个临界资源的锁标记
B. 线程进入锁池时,不会释放本身已经占有的资源,而是带着锁标记进入其他临界
资源的锁池
C. t1线程拿着s1的标记进入s2的锁池,t2线程拿着s2的标记进入s1的锁池
3)线程间通信
A. wait() :
I. “临界资源.wait()”必须定义在对临界资源加锁的同步代码块里
II. 当线程运行了wait方法后,会放弃手边拥有的所有“资源”,并且将自己送入
到“等待队列”中,直到有其他线程调用“临界资源的notify或者notifyAll”
方法,将线程放出
B. notify() /notifyAll() :释放临界资源等待队列里的一个、所有的线程,方法对当前
线程没有影响。
关于修饰符的兼容问题
1)Synchronized和abstract不能同时出现。
2)synchronized和 static 能不能同时出现 -- 可以ArrayList和Vector的区别;Hashtable和HashMap的区别?
答: Vector和Hashtable是线程安全的,他们的所有方法全部是“同步”的,所有访问
这种集合类的线程全部串行通过。