綫程,進程
什么是线程?什么是进程?
进程就是应用程序,任何一个应用程序打开,操作系统都会分配一段连续的空间给程序使用,进 程就是管理这段空间,包含执行程序的代码以及资源。 线程是应用程序的执行单元,所有的代码都是有线程来执行的。任何程序必须有一条线程,就
是主线程,如果所有的线程都退出了,进程也就退出了。
1,线程Thread类
static Thread currentThread() ,静态方法,获取当前的线程。
String getName() 获取线程名称,主线程:main,子线程默认叫做Thread-0/1/2/3...
static Thread sleep(时间) 当前线程睡眠一段时间,单位是毫秒
class 类名 extends Thread{
public void run(){
//子线程执行的代码
}
}
类名 th = new 类名();
//开始启动了
th.start();
使用线程,必须重写他的run方法,否则这条线程,没有任何用处
2,接口Runnable
为什么要使用接口,不直接使用Thread类呢?
因为java是单继承,很多时候,我们的类必须继承父类,又同时需要实现线程的功能。就必须 使用Runnable接口.
和Thread不同的点,Runnable只有一个抽象方法run,我们必须实现run方法,这个run方法 就是在线程中执行的代码。
class 类名 extends 其他的父类 implements Runnable{
public void run(){
}
}
类名 runable = new 类名();
//使用Thread的有参构造方法,将runnable传进去
Thread th = new Thread(runnable);
th.start(); //Thread的start方法会去执行run方法,run方法中回去调用runnable的ru n方法。
3,start和run的区别
start才是开启新线程,并且去执行run方法。
直接调用run,只是在当前线程中去执行代码。
永远不要直接使用run方法。而是使用start
4,线程的生命周期
新建: 唯一一个可以调用start方法的状态,只有在最初刚开始new对象的时候,才是这个状 态
就绪/运行: 线程已经开始执行了,调用start方法,如果能拿到cpu执行权,就是运行状态, 否则是就绪状态。
阻塞:调用了线程休眠sleep,线程加入join,线程等待wait等方法,没有cpu的执行权,直到 醒来,进入就绪状态。
死亡: 线程执行完毕后,到了死亡的状态,什么都不能做。
任何一个线程,new创建对象后只能运行一次start方法。
5,优先级
线程的优先级 根据操作系统来的。java又和操作系统无关。
java做了一对常量。java分为10个优先级
所有的线程,在没有做处理的时候,都是5 NORM_PRIORITY 5
线程的优先级,不能作为代码的逻辑判断,并不是优先级高一定先执行完毕。
public static final int MAX_PRIORITY 10
public static final int MIN_PRIORITY 1
public static final int NORM_PRIORITY 5
6,回调接口
1. 同步方法
2. 异步异步
callback的格式
1. 定制回调接口 interface 接口名称
2. 私有变量set传入,方法参数,构造方法传入
3. 在需要回调的地方,调用接口中的方法
7,线程控制
join:让另外一条线程,先执行,执行完毕或者执行一段时间后,自己在执行
setDaemon(true):设置线程为后台线程,如果所有的前台线程全部退出,程序退出,后台线 程自动退出。
默认是前台线程。该方法一定要在线程start之前调用,否则出现异常。
//一般用:
静态方法 sleep(毫秒); 让当前线程休眠一段时间
yield():让步,让给同优先级的线程。
8,綫程同步
因为线程可能在任何时间卧倒,代码如果不做同步,可能会出现问题
使用關鍵字 synchronized
在同步代码块的时候,多条线程必须保证同步锁是唯一的。
在同步方法上,同步锁是this,保证多条线程是访问的同一个对象的方法。
9,單力例模式
整个工程中,该类只有一个对象 常用有饿汉式和懒汉式,实现方法:
私有构造方法
私有本类静态对象
公开静态方法返回本类对象 getInstance();
饿汉式在创建静态对象的时候,直接构建对象,懒汉式在getInstance中创建对象,存在线程 问题。
10,线程池
装线程的。线程的容器。
Executor线程池的根接口,只有一个方法
void execute(Runnable command) 执行一个runnable
ExecutorService是线程池的接口,有一个重要的方法
shutdown() ; 关闭线程池,不会结束当前线程池队列中的任务,会执行完毕后关闭,但是一 旦关闭,不允许在新增任务。
Executors工具类,为我们提供了4个线程池
1,newCachedThreadPool() ; 缓存线程池, 可以重用线程。
2,newFixedThreadPool(); 固定并发线程池,并发数固定,每次执行完毕再去队列
3,newSingleThreadExecutor(); 同固定线程池,只是固定数量为1
4,newScheduledThreadPool(); 定时器
schedule延迟执行
scheduleWithFixedDelay周期执行 shutdown后会关闭
**Timer 定时器类
创建定时器的对象
Timer timer = new Timer();
创建任务,TimeTask 实现了 Runnable,给了一个cancel的同步关闭方法。
TimeTask timeTast = new TimeTask(){重写run方法};
执行延迟,或者周期任务
timer.schedule(task,延迟时间,周期时间);
关闭
timer.cancel();
线程通信
1. //在某个对象上保持一致。
2. wait() 线程等待
3. notify() 线程唤醒
4. 必须在同步代码块(对象锁)中,才能调用这些方法。
5.必须调用对象锁的 wait和notify
6.notify只会随机唤醒当前等待的线程之一,如果需要都唤醒使用notifyAll