1、程序
程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念
2、进程
进程是执行程序的一次执行过程,他是一个动态的概念,是系统资源分配的单位
3、线程
一个进程中可以包含若干个线程,线程是cpu调度和执行的单位,每个线程会有自己的工作内存,控制不当会导致数据不一致,导致线程不安全
3.1线程的创建
- 继承Thread类
自定义线程类继承Thread类,重写run方法,定义自定义类对象,调用对象的start()方法启动线程,线程启动后不一定立即执行,由cpu调度 - 实现Runnable接口
自定义类实现Runnable接口,实现run方法,编写线程执行体,创建线程对象并将自定义类作为参数传给线程对象,然后启动线程对象 - 实现callable接口
建议使用Runnable接口,避免单继承局限性,方便同一个对象被多个线程使用,会存在线程不安全问题
3.2线程状态
创建、就绪、运行、阻塞和终止
- 线程停止,不建议使用线程自带的stop,一般使用标识符进行的true或者false进行判断
- 线程休眠,sleep(),单位是毫秒,线程休眠完成后达到就绪状态;可以模拟网络延时;每一个对象都有一个锁,sleep不会释放锁;
- 线程礼让,让当前正在执行的线程暂停,但不阻塞,从运行态转为就绪态,礼让不一定成功
- 线程合并,待此线程执行完成后,在执行其他线程,其他线程被阻塞
3.3线程状态观察,thread.getState()
线程状态,可以处于以下状态之一
- NEW,尚未启动的线程处于此状态
- RUNNABLE,在java虚拟机中执行的线程状态
- BLOCKED,被阻塞等待监视锁定的线程处于此状态
- WAITING,正在等待另一个线程执行特定动作的线程处于此状态
- TIMED_WAITING,正在等待另一个线程动作达到指定的等待时间处于此状态
- TERMINATED, 已经退出的线程
3.4线程优先级
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程执行
使用以下方法获取优先级或设置优先级,getPriority(),setPriority(),一般是1-10
3.5守护线程
线程分为用户线程和守护线程,虚拟机必须确保用户线程执行完毕,不需要等守护线程执行完毕
setDaemon(true),默认false表示用户线程,ture为守护线程
3.6线程同步
并发,同一个对象被多个线程同时操作,会引发线程不安全
- 同步方法:synchronized 方法,public synchronized void method(){},控制对对象的访问,每个对象对应一把锁,每个方法都必须获得调用该方法对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行,默认锁this,即这个类;会影响效率
-- 同步块,synchronized代码块,synchronized (obj){},synchronized锁的是变化的对象,是隐式锁
3.7死锁
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致多个线程都在等待对方释放资源,都停止执行的情形。
产生死锁的四个必要条件:
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持:一个进程因请求资源而被阻塞时,对已经获得的资源保持不放
- 不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
3.8Lock锁
ReentranLock lock 可重入锁,lock.lock()加锁;lock.unlock();解锁
- 显式锁
- 使用lock锁,jvm将花费较少的时间来调度线程,性能更好
- 使用顺序 Lock>同步代码块>同步方法
3.9线程池
问题:经常创建和销毁、使用量特别大的资源,比如并发下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回去。可以避免频繁创建、销毁线程,实现重复利用。
线程池相关api:
ExecutorService和Executors
ExecutorService线程池接口,
execute():执行任务,没有返回值,一般用来执行Runnable
submit():执行任务,有返回值,一般来执行Callable
shutdown():关闭连接池
Executores:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
实现Runnable接口举例如下:
package demo1;
public class Race implements Runnable{
private String winner;
@Override
public void run() {
for(int i=0;i<=100;i++){
if(Thread.currentThread().getName()=="兔子" && i%10==0){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
boolean flag = gameOver(i);
if(flag){
break;
}
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
}
}
public boolean gameOver(int steps){
if(winner!=null){
return true;
}{
if(steps==100){
winner=Thread.currentThread().getName();
System.out.println("winner is "+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race=new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
标签:状态,Runnable,对象,程序,阻塞,线程,进程,执行
From: https://www.cnblogs.com/bobstudyjava/p/17103681.html