进程:
1、进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间,当我们使用微信,又启动了一个进程,操作系统将为微信分配新的内存空间
2、进程是程序的一次执行过程,或是正在运行的一个程序,是动态过程;有它自身的产生、存在和消亡的过程
线程:
1.线程由进程创建的,是进程的一个实体
2.一个进程可以拥有多个线程
单线程:同一时刻,只允许执行一个线程
多线程:同一个时刻,可以执行多个线程
并发:同一时刻,多个任务交替执行,造成一种“貌似同时”的错觉。简单的说,单核cpu实现的多任务就是并发
并行:同一时刻,多个任务同时执行。多核cpu可以实现并行
- /*
- 1.当一个类继承了Thread类,该类就可以当作线程使用
- 2.重写run方法,写上自己的业务逻辑
- 3.实现了Runnable接口的run方法
- 4.当main线程启动一个子线程Thread-0,主线程不会阻塞,会继续执行
- 5.此时主线程和子线程交替执行
- */
- //继承Thread类
- class Cat extends Thread{
- @Override
- public void run() {//重写run方法,完成自己的业务逻辑
- int times = 0;
- while (true) {
- System.out.println("喵喵~"+(times++)+Thread.currentThread());
- //让该线程休眠1秒
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (times == 80){
- break;//退出while循环,线程结束
- }
- }
- }
- }
- //实现Runnable接口
- class A implements Runnable{
- int count=0;
- @Override
- public void run() {
- while (true) {
- System.out.println("hi"+(count++));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (count == 10)
- break;
- }
- }
- }
线程终止:
1、当线程完成任务后,会自动退出
2、还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
线程常用方法:
一、
1.setName:设置线程名称,使之与参数name相同
2.getName:返回该线程的名称
3.start:启动新的线程,使该线程开始执行(底层调用该线程的start0方法)
4.run:调用线程对象run方法(只是简单的方法调用,不会启动新的线程)
5.setPriority:更改线程的优先级
6.getPriority:获取线程的优先级
7.sleep:在指定的毫秒数内让当前正在执行的线程休眠
8.interrupt:中断线程(并没有真正的结束线程,一般用于中断正在休眠的线程)
二、
1、yield:线程的礼让。让出cpu,让其它线程执行,但礼让时间不确定,所以也不一定礼让成功
2、join:线程的插队。插队的线程一旦成功,则肯定先执行完插入的线程所有的任务
- public class Study {
- @SuppressWarnings({"all"})
- public static void main(String[] args) throws InterruptedException {
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- int count = 0;
- while (true){
- System.out.println("子线程:"+"hello"+(++count));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (count == 20)
- break;
- }
- }
- });
- thread.start();
- for (int i = 0; i < 20; i++) {
- System.out.println("主线程:"+i);
- Thread.sleep(1000);
- if (i == 4){
- System.out.println("子线程插队");
- thread.join();
- }
- }
- }
- }
用户线程和守护线程:
1、用户线程:也叫工作线程,当线程的任务执行完成或通知方式结束
2、守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
3、常见的守护线程:垃圾回收机制
怎么将用户线程设置为守护线程:再调用start方法前,先调用setDaemon方法
线程的七大状态:
NEW:尚未启动的线程处于此状态
RUNNABLE:在java虚拟机中执行的线程处于此状态(细分为Ready和Running两个状态)
BLOCKED:被阻塞等待监控器锁定的线程处于此状态
WAITING:正在等待另一个线程执行特定动作的线程处于此状态
TIME_WAITING:正在等待另一个线程执行动作达到指定等待时间的线程处于此状态
TERMINATED:已经退出的线程处于此状态
线程同步机制:
1、在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,在保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性
2、也可以这样理解:线程同步,即当有一个线程在对内存进行操作时,其它线程都不可以对这个内存地址进行操作,直到该线程完成操作,其它线程才能对该内存地址进行操作
同步具体方法:
1.同步代码块
synchronized(对象){ //得到对象的锁,才能操作同步代码
//需要被同步代码; }
2.synchronized还可以放在方法中声明,表示整个方法为同步方法
public synchronized void m(String name){
//需要被同步的代码; }
互斥锁:
1.java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性
2.每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象
3.关键字synchronized来与对象的互斥锁联系,当某个对象用synchronized修饰,表明该对象在任一时刻只能由一个线程访问
4.同步的局限性:导致程序的执行效率要降低
5.同步方法(非静态的)的锁可以是this,也可以是其它对象(要求是同一个对象)
6.同步方法(静态的)的锁为当前类本身
线程的死锁:
概念:多个线程都占用了对方的锁资源,但不肯相让,导致了死锁,在编程中一定要避免死锁的发生
- class DeadLockDemo extends Thread{
- private static Object o1 = new Object();
- private static Object o2 = new Object();
- boolean flag;
- public DeadLockDemo(boolean flag){
- this.flag=flag;
- }
-
- @Override
- public void run() {
- /*
- 1.如果flag为T,线程A就会先得到/持有o1对象锁,然后尝试去获取o2对象锁
- 2.如果线程A得不到o2对象锁,就会Blocked
- 3.如果flag为F,线程B就会先得到/持有o2对象锁,然后尝试去获取o1对象锁
- 4.如果线程B得不到o1对象锁,就会Blocked
- */
- if (flag){
- synchronized (o1){
- System.out.println(Thread.currentThread().getName()+"进入1");
- synchronized (o2){
- System.out.println(Thread.currentThread().getName()+"进入2");
- }
- }
- }else{
- synchronized (o2){
- System.out.println(Thread.currentThread().getName()+"进入3");
- synchronized (o1){
- System.out.println(Thread.currentThread().getName()+"进入4");
- }
- }
- }
- }
- }
释放锁:
1、当前线程的同步方法、同步代码块执行结束
2、当前线程在同步代码块、同步方法中遇到break、return
3、当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束
4、当前线程在同步代码块,同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁
下面操作不会释放锁:
1.线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行,不会释放锁
2.线程执行同步代码块时,其它线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁