进程与线程

本文详细介绍了进程和线程的概念,以及Java中的线程处理。从进程的内存空间独立,到线程作为进程的执行单元,多线程如何提高程序效率。深入探讨了并行与并发的区别,同步与异步的实现。通过Java Thread类,讲解了创建线程的三种方式,并阐述了线程的生命周期,包括新生、就绪、运行、阻塞和终止状态。此外,还讨论了多线程访问资源的问题,重点介绍了`synchronized`关键字用于线程同步的原理和使用方法,以及解决死锁的策略。
摘要由CSDN通过智能技术生成

进程Process

进程就是操作系统中执行的程序,一个程序就是一个执行的进程实体

每个运行中的进程,都有属于它的内存空间,各个进程互不影响

线程Thread

线程是一个进程中的执行单元,一个进程中可以有多个线程

多个线程,可以访问同一个进程中的资源

每个线程都有一个独立的栈空间,这些线程所在的占空间位于同一个进程空间中

多线程

如果一个进程中,同时在执行多个线程,就成为多线程

多线程你可以提高程序执行的效率,入多个窗口买票,可以加快卖票的效率

每个执行的Java程序,都是多线程执行,main方法称为主线程,还有gc线程(垃圾回收机制)在同时运行

如: 有一个工厂,工厂中有很多车间,每个车间有很多流水线

工厂就是内存,车间就是进程,每个流水线都是一个进程中的多个线程.

并行和并发

并行

每个进程同时各自执行,称为并行

并发

多个线程同时执行,称为并发

同步与异步

同步

所有的任务排队执行,成功为同步执行.

异步

在执行任务A的同时执行任务B称为异步执行

Java中的线程Thread类

java中线程以对象的形式存在

Thread表示线程类

获取线程对象

  • 获取当前正在运行的的线程对象
//获取当前正在运行的线程对象
Thread ct = Thread.currentThread();
  • 创建一个线程对象

构造方法

常用构造方法说明
Thread()创建一个默认的线程对象
Thread(String name)创建一个指定名称的线程对象
Thread(Runnable target)将一个Runnable对象包装为线程对象
Thread(Runnable target,String name)将一个Runnable对象包装为线程对象并指定名称

常用方法

方法作用
getId()获取线程的ID主线默认为1
getName()获取线程名,主线程名为main,也可以用setName设置名字
getPriority()得到该线程的优先级,默认线程优先级为5
getState()判断该线程是否属于守护线程,也可通过setDaemon()更改
setName(String name)设置线程名
setPriority(int priority)设置该线程的优先级,设置的范围为: 1-10 ,越大越优先
isDaemon()判断该线程是否属于守护线程
setDaemon(boolean on)设置该线程是否是守护线程
start()让线程进入就绪状态
run()线程获得执行权执行的方法
Thread.sleep(long m)设置当前线程休眠m毫秒
Thread.currentThread();获取当前执行的线程对象
Thread.yield()线程让步

实现多线程

方式一: 定义一个类继承Thread类

  • 创建一个类继承Thread

  • 重写Thread中的run()方法.

  • 创建自定义的线程子类,调用start()方法

自定义线程类Thread的子类

public class ThreadA extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(super.getName()+" : " + i);
        }
    }
}

方式二:实现Runnable接口

由于Java是单继承,如果某个类已经使用了extes关键字,可以使用Runnable接口实现多线程

  • 自定义一个类,实现Runnable接口

  • 重写run方法

  • 创建Runnable接口的实现类对象

  • 使用Thread参数为Runnabel的构造方法,上一步的对象作为参数,包装为Thread对象

  • 调用start()方法

自定义Runnable接口的实现类

public class ThreadB implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+" : " + i);
        }
    }
}

main

        Thread myThread = new Thread(new ThreadB(),"My线程B");
        Thread myThread2 = new ThreadA();
        myThread2.setName("我的线程A");
        myThread2.start();
        myThread.start();

方式三:使用匿名内部类

如果不想创建一个Runnable的实现类,就可以使用匿名内部类充当Runnable接口的实现类

 //声明内部类,并且调用start()方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+" : "+i);
                }
            }
        },"内部类线程").start();

线程的生命周期

线程的初始化到终止的整个过程,称为现成的生命周期

新生状态

当线程对象被创建后,进入新生状态. new了一个线程对象时

就绪状态

当某个线程对象调用了start()方法后,就进入了就绪状态

在这个状态下,线程对象不会做任何事情,只在等他的CPU调度.

运行状态

当某个线程对象得到CPU时间片(CPU执行这个线程的机会所给的时间),则进入运行状态,开始执行run()方法

不会等待run()方法执行完毕.只会在指定的时间内尽可能地执行这个run()方法,只要调用玩run()方法后就会在进入就绪状态

阻塞状态

如果某个线程遇到了sleep()方法或者wait()方法就会进入阻塞状态

sleep()发给发会在指定时间后让线程重新就绪

wati()方法只有在被调用notify()或notifyAll()方法唤醒后才能重新就绪.

终止状态

当某个现成的run()方法中的的所有内容都执行完,就会进入终止状态,意味着该线程的使命已经完成.

守护线程

如果将一个线程setDeamon(true),表示该线程为守护线程.

守护线程会随着其他非守护线程终止而终止

多线程访问同一个资源

如银行存款100,同一时刻在手机和ATM一起取出,如果用多线程模拟,可能会出现两个线程都取出100的情况,需避免这种形况发生

解决方案

让线程同步(排队)执行即可.某个线程执行run()时,让其他线程等带run()方法的内容执行完毕.

synchronized关键字

这个关键字可以先修饰方法或者代码块

修饰方法

写在方法的返回值之前,这是该方法就成为同步方法

public synchronized void fun() {

    }

这时就会排队执行该方法

修饰代码块

当某个对象会被多个线程同时操作时,可以使用

synchronized (被同时操作的对象){ //排队执行的代码

}

这样在涉及到该对象操作时,就会排队执行

写在一个独立的 { } 前,称为一个同步的代码块

代码块在类创建对象时执行

synchronized (要同步的对象或this){
    //排队执行的代码    

}

原理

每个对象默认都有一把"锁",当某个线程运行到被synchronized修饰的方法时,该对象就会拥有这把锁,再拥有锁过程中,其他线程不能同时访问该方法,只有等待其结束后,才会释放这把锁

使用synchronized修饰后的锁称为"悲观锁".

方法被synchronized修饰后称为同步方法,就会让原本多线程变成了单线程(异步变为同步).

死锁的解决方式

方式一:

让两个线程获取资源的顺序一致,

方式二:

让两个线程在获取资源A和资源B之前再获取第三个资源,对第三个资源使用

synchronized进行同步,这样某个线程在获取第三个资源后,将后续内容执行完毕,其他线程才能执行

就是在死锁外再增加一层锁,在多线程情况中,当有线程拥有该锁时,其他线程不能访问该锁内的两个资源.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值