关于java多线程的学习总结
1.线程与进程的区
进程:程序执行的一次过程,系统运行的基本单位,因此是动态的。系统运行一个程序就是一个进程创建,运行,到消亡的过程。
线程:与进程相似,比进程更小的单位,一个进程可以产生多个线程,线程可以共享同一块内存空间和系统资源,负担小也被称为轻量级进程。
2.什么是多线程:多个线程同时运行或交替运行。
3.为什么使用多线程而不是多进程:
因为线程是轻量级进程,是程序执行的最小单位。线程间的切换和调度的成本远小于进程。
4.同步和异步:通常形容一次方法调用。
同步:执行完后返回:
异步:立即返回
5.线程分类
用户线程:运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程
守护线程:运行在后台也被,为其他前台线程服务。
特点:一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作
适用场景:数据库连接池中的检测线程,JVM虚拟机启动后的检测线程
最常见的守护线程:垃圾回收线程
6.实现多线程的方式
1.继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
for(int i = 0; i < 4;i++) {
//获取当前线程资源的名字
System.out.println(Thread.currentThread().getName()+"第" + i + "次运行");
}
System.out.println(Thread.currentThread().getName() + "运行结束");
}
}
public class ThreadMain {
//主类
public static void main(String[] args) {
System.out.println("继承Thread方法");
MyThread a = new MyThread();
MyThread b = new MyThread();
a.start();
b.start();
}
}
2.实现Runable接口
public class MyThread implements Runnable {
@Override
public void run() {
for(int i = 0; i < 4;i++) {
System.out.println(Thread.currentThread().getName()+"第" + i + "次运行");
}
System.out.println(Thread.currentThread().getName() + "运行结束");
}
}
public static void main(String[] args) {
System.out.println("实现Runable方法");
Thread thread1 = new Thread(new MyThread());
Thread thread2 = new Thread(new MyThread());
thread1.start();
thread2.start();
}
3.使用线程池
线程池的优势:低资源消耗,提高响应速度,提高线程的可管理性。
线程池包括:定长线程池,定时线程池,可缓存线程池,单线程化线程池。
定长线程池(FixedThreadPool)
特点:只有核心线程池,线程数固定,执行完立即回收,任务队列为链表结构的有界队列。
适合:控制线程最大并发数
public class MyFixedThreadPool {
public static void main(String []args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//lambda表达式方法实现runable接口
Runnable myRunable = ()->{
System.out.println("开始执行");
for(int i = 0; i < 4 ;i++)
System.out.println(Thread.currentThread().getName()+"第"+i+"次执行" );
System.out.println("执行结束");
};
//提交任务
fixedThreadPool.execute(myRunable);
fixedThreadPool.shutdown();
}
}
定时线程池(ScheduledThreadPool)
特点:核心线程数固定,非核心不限,执行后10ms回收。任务队列为阻塞队列。
适合:定时或周期性
public class MyScheduleYThreadPool {
public static void main(String []args) throws InterruptedException {
//格式控制
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
Runnable myRunable = ()->{
System.out.println(Thread.currentThread().getName()+":"+ format.format(new Date()) );
};
//提交任务
//延迟0s后 每隔5秒执行任务
scheduledThreadPool.scheduleAtFixedRate(myRunable,0, 5, TimeUnit.SECONDS);
Thread.sleep(20000);
scheduledThreadPool.shutdown();
}
}
可缓存线程(CachedThreadPool)
特点:无核心线程,非核心不限,执行后闲置60s后回收。任务队列为不存储元素的阻塞队列
适合:执行量大耗时少
public class MyCachedThreadPool {
public static void main(String[] args) {
ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
Runnable myRunable = ()->{
System.out.println("开始执行");
for(int i = 0; i < 4 ;i++)
System.out.println(Thread.currentThread().getName()+"第"+i+"次执行" );
System.out.println("执行结束");
};
//提交任务
cacheThreadPool.execute(myRunable);
cacheThreadPool.shutdown();
}
}
单线程化线程池(SingleThreadExecutor)
特点:只有一个核心线程,无非核心线程,执行后立刻回收。任务队列为链表结构的有界队列
适合:不适合并发但可能引起IO阻塞性及可能引起IO阻塞性影响
UI线程响应的操作
public class MySingleThreadExecutor {
public static void main(String []args) {
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
Runnable myRunable = ()->{
System.out.println("开始执行");
for(int i = 0; i < 4 ;i++)
System.out.println(Thread.currentThread().getName()+"第"+i+"次执行" );
System.out.println("执行结束");
};
singleThreadPool.execute(myRunable);
}
}