线程和进程
线程:
线程是程序执行时的最小单位,它是进程的一个流程,是CPU调度和分派的基本单位.
进程:
进程是资源(CPU,内存等)分配的基本单位,它是程序执行时的一个实例.
线程和进程的区别:
1.每个进程都有自己独立的代码和数据空间,内存空间
2.一类线程共享进程的资源
3.一个进程包含1到多个线程
4.进程是资源分配的最小单位
5.线程是CPU调度的最小单位
线程的五个状态
新建(NEW)----- new Thread(),创建一个线程
就绪(RUNABLE)-----start(),就绪不是运行,就绪状态的线程会处于就绪队列中,等待CPU的调度.
运行(RUNNING)-----当CPU为某个线程分配时间片时,这个线程就开始执行了.
阻塞(BLOCKED)-----sleep(),阻止线程的正常执行,等待阻塞解除.
死亡(TERMINATED)-----线程结束
注意:
- 如果一个线程一旦终止,没有办法恢复,就算重新开启也不是原来的线程
- 阻塞状态解除,没有办法直接恢复运行状态,都会进入就绪状态.
线程进入终止状态的方式
- 执行完毕
- 通过外部干涉调用:①stop(),destroy()②通过外部标识判断**—>推荐使用
线程进入阻塞状态的方式
- sleep()
sleep(毫秒数)线程睡眠
a. 可以放大问题发生的可能性
b.模拟网络延时 - jion(),插队,在start()之后
- wait()
- IO操作
注意:
程序进入阻塞状态,让出CPU资源,
sleep()方法不会释放锁的资源
sleep()抱着对象资源睡觉,不会释放
多线程的3种创建方式
1.继承Thread类,重写run()方法
2.实现Runnable接口,重写run()方法
-避免单继承的局限性
-实现资源共享
3.实现Callable接口,重写Call方法
-使用麻烦
-抛异常,具有返回值
----执行:
①创建执行服务
ExecutorSerive ex = Executors.newFixedThreadPool(2);
②提交执行线程
Future result1 = ex.submit(match);
Future result2 = ex.submit(match);
③获取执行结果
Integer i1 = result1.get();
Integer i2 = result2.get();
System.out.println(i1+"—>"+i2);
④关闭执行服务
ex.shutdown();
多线程安全问题
多个线程,同时操作同一资源的时候,有可能出现线程不安全的问题.
Synchronized同步锁:同步方法和同步类
同步方法:
成员方法和静态方法
锁静态方法相当于锁类
同步块
Synchronized(this|类|资源){…}
this---->对象
类---->类名.class
资源---->成员变量---->只能是引用数据类型
注意:
锁的范围太大,效率低
锁的范围太小,锁不住
锁一定要锁不变的内容,变的锁不住,自定义的引用数据类型的对象地址,能锁得住
锁:块,this,对象—>
指代当前调用成员方法的对象
如果对象中存在多个资源,相当于把一整个对象的所有资源全部锁住了.
如果只需要锁对象的某个资源,就锁资源.
线程通信(生产者消者模式)
wait():线程处于等待状态
释放对象的锁,cpu的资源
notify():唤醒对方正在处于等待池中的线程
没有对象的资源,就算是被唤醒也无法执行,必须要获取到队形的锁才能有资格执行
notifyAll()
唤醒全部
案例:人和车根据信号灯通行马路
package com.shsxt0718;
public class StreetDemo02 {
public static void main(String[] args) {
Street s = new Street();
new Thread(new Person(s)).start();
new Thread(new Car(s)).start();
}
}
class Street{
private boolean flag = false;
//南北 车 false
synchronized void ns() {
if(flag == true) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("车在走");
this.notify();
flag = true;
}
}
synchronized void we() {
if(flag == false) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("人在走");
this.notify();
flag = false;
}
}
}
class Person implements Runnable {
Street street;
public Person(Street street) {
super();
this.street = street;
}
@Override
public void run() {
while(true) {
street.we();
}
}
}
东西 人 true
class Car implements Runnable {
Street street;
public Car(Street street) {
super();
this.street = street;
}
@Override
public void run() {
while(true) {
street.ns();
}
}
}