在学习多线程之前,我们首先来了解一下什么线程和进程,当一个程序被执行后,会分配一片内存区域,程序初始化的时候,也就是一个进程加在过程中,会有多个线程被执行,操作系统os会将多个线程通过io桥交给cpu处理和计算。那么什么是线程和进程呢?从专业角度解释就是,进程是分配资源的基本单位,线程就是调用执行的基本单位。
1.程序加载的执行顺序:
①执行应用程序后会在内存中分配一片区域,开启一个进程
②将进程中的主线程(main方法)交给cpu,若一个主线程中有多个线程,例如A线程和B线程,操作系统os会分别交给cpu执行处理和计算,也就是我们说的操作系统os的线程调度。
③在多个线程执行期间又会有线程切换,例如线程A中的指令和数据,将指令交给cpu的寄存器(计数器)、数据交给cpu的Register,通过cpu的ALU计算单元计算,当这个时间片该线程没有计算处理完成,B线程开启执行,cpu会将执行指令和数据放到cache中,A线程处于等待阶段,B线程再执行上③操作,直到A、B线程都执行完成。
2.线程数(线程池创建核心线程的数量)和cpu核心数的关系
并不是线程数越多,效率就越高。这和cpu的核心数有一定关系。
根据cpu的核心数设定线程数量(理想状态),但也需要压测来找到合适的线程数量。
计算公式:Nthread=Ncpu * Ucpu *(1+W/C)
Ncpu是cpu的核的数目,可以通过Runtime.getRuntime().availableprocessors()得到。
Ucpu是期望的cpu利用率(该值应该介于0和1之间)
W/C是等待时间与计算时间的比率。
3.创建线程都有哪几种方式
public class CreatThread {
/**
*
* 继承Thread类
*
* */
static class MyThread extends Thread{
@Override
public void run(){
System.out.println("MyThread:Hello world");
}
}
/**
* 实现Runnable接口
*
* */
static class MyRun implements Runnable{
@Override
public void run(){
System.out.println("MyRun:Hello world");
}
}
/**
* 实现Callable接口,重写call()方法,带返回值的
*
* */
static class Mycall implements Callable<String>{
@Override
public String call(){
System.out.println("MyCall:Hello world");
return "success";
}
}
public static void main(String[] args) {
new MyThread().start();
new Thread(new MyRun()).start();
//new Thread创建Mycall
FutureTask<String> task =new FutureTask<>(new MyCall());
Thread thread=new Thread(task);
thread.start();
//线程池创建Mycall
ExecutorService executorService=Executors.newCachedThreadPool();
Future<String> f=executorService.submit(new MyCall());
try{
System.out.println("new Thread创建Mycall,返回值:"+task.get());
System.out.println("线程池创建MyCall方法"+"返回值:"+f.get());//get()是阻塞类型的
}catch (Exception e){
e.printStackTrace();
}
}
综上所述:
创建线程有以下几种方式:
1.继承Thread类方法
2.实现Runnable接口
3.实现Callable接口,有返回值
4.线程池创建
4线程的生命周期
1.New状态:新创建了一个线程对象,在没调用start()方法前的状态。
2.RUNNABLE状态:当new出的线程调用start()方法后,RUNNABLE状态,等待被线程调度选中,获取cpu的使用权。
3.RUNNING状态:线程调度器选中执行后状态变为RUNNING状态,线程调用thread.yield()方法,主动让出cpu使用权,挂起变成READY状态。
4.TIMED WAITING状态:当线程调用Thread.sleep(time)睡一段时间,然后时间过后自动唤醒,在这之间的状态,休眠时间过后又会进入到RUNNABLE状态。
5.WAITING(忙等待阶段)状态:例如调用o.wait(),t.join(),LockSupport.park(),lock.lock(),在没手动释放锁之前的状态。手动释放锁后o.notify(),o.notifyAll(),LockSupport.unpark(),lock.unlock(),线程状态又会进入到RUNNABLE状态
6.BLOCKED状态:等待进入同步代码的锁或者队列时的状态,阻塞状态。
7.TERMINATED状态:线程消亡状态。
5。线程的“打断”-设置中断标志位(interrupt)
目的是如何更好的结束线程
thread.interrupt() -打断某个线程(设置标志位)
thread.isInterrupted-查询某线程是否被打算
static Interrupted()-查询当前线程是否被打断过,并重置打断标志