一:概念
了解线程,得先了解进程。
进程:是具有一定独立功能的程序关于某个数据集合的一次运行活动,它是系统进行资源分配和调度的一个独立单位。
线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
关系:简而言之,一个程序至少有一个进程,一个进程至少有一个线程。进程和线程的主要差别在于他们是不同的操作系统资源管理方式。
二.创建线程
2.1:设计一个继承java.lang.Thread的子类,覆盖Thread类的run方法。
2.2:设计一个实现Runnable接口的类,实现它的run方法。
启动线程:调用start()方法
运行线程:调用run()方法
三:线程之间的状态
3.1:创建状态:使用new运算符创建一个线程后,该线程处于创建状态。
3.2:就绪状态:用start()方法启动一个线程后,系统为该线程分配除处理机外的所有资源,线程就进入就绪队列排队,等待处理机制调度。
3.3:运行状态:轮到线程占用CPU资源时,JVM将CPU使用权切换给该线程,该线程就可以开始自己的生命周期。
3.4:阻塞状态:正在运行的线程让出CPU使用权,JVM将CPU资源切换给其它线程。阻塞主要有休眠阻塞、等待阻塞、互斥阻塞和其它阻塞等。
3.5:死亡状态:线程运行结束后进入死亡状态。
四:线程的两个特性
多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现。
线程共享变量的过程:在多个线程之间共享了Count类的一个对象,这个对象是被创建在主内存(堆内存)中,每个线程都有自己的工作内存(线程栈)。操作共享对象时,首先从主内存复制Count对象到工作内存中,修改Count对象,最后用工作内存Count刷新主内存Count。
4.1:可见性
当一个对象在工作内存中都存在副本,一但一个线程修改了共享变量,其他线程能看见修改后的值。
4.2:有效性
多个线程执行时,CPU的调度是随机的。保证线程有序的执行,这就是有效性。
五:线程的同步机制
5.1:synchronized
每个锁对象都有两个队列,分别为就绪队列,阻塞队列。
就绪队列存放了将要获得锁的线程,阻塞队列存放了被阻塞的线程,当一个线程被唤醒后,才会进入就绪队列,等待CPU的调度,反之,进入阻塞队列,等待被唤醒。
一个线程执行互斥代码过程如下:
1.获得同步锁;
2.清空工作内存;
3.从主内存拷贝对象副本到工作内存;
4.执行代码(计算或者输出等);
5.刷新主内存数据;
6.释放同步锁。
5.2:volatile
一个变量可以被volatile修饰,在这种情况下内存模型(主内存和线程工作内存)确保所有线程可以看到一致的变量值
六:线程池
池的最终目的都是节约资源,以更小的开销做更多的事情,从而提高性能。
创建线程池的方式有四种:
6.1.创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程。
ExecutorService threadPool=Executors.newFixedThreadPool(3);
创建了一个固定大小的线程池,容量为3,在FixedThreadPool中,有一个固定大小的池,如果当前需要执行的任务超过了池大小,那么多于的任务等待状态,直到有空闲下来的线程执行任务,而当执行的任务小于池大小,空闲的线程也不会去销毁。
6.2.创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
ExecutorService threadPool=Executors.newCachedThreadPool();//线程池的大小会根据执行的任务数动态分配
CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来,如果线程有可用的,就使用之前创建好的线程,如果没有可用的,就新创建线程。
6.3.创建一个使用单个worker线程的Executor,以无界队列方式来运行该线程。
ExecutorService threadPool=Executors.newSingleThreadExecutor();
SingleThreadExecutor得到的是一个单个的线程,这个线程会保证你的任务执行完成,如果当前线程意外终止,会创建一个新线程继续执行任务,这和我们直接创建线程不同,也和newFixedThreadPool(1)不同。
6.4.创建一个可安排在给定延迟后运行命令或者定期地执行的线程池。
ScheduledExecutorService threadPool=Executors.newScheduledThreadPool(3);
ScheduledThreadPool可以定时的或延时的执行任务。
七:锁对象Lock
Lock是java.util.concurrent.locks包下的接口,Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题.
与synchronized不同:
用sychronized修饰的方法或者语句块在代码执行完之后锁自动释放,而用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内。
以上就是动力节点java培训机构的小编针对“Java线程培训:Java线程内容详解”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习