进程和线程

1. 进程和线程的基本概念

进程是系统分配资源的基本单位. 进程是操作系统对正在运行程序的一种抽象,可以将进程看作程序的一次运行。

线程是系统调度执行的基本单位.  一个线程是一个"执行流". 线程自己不拥有系统资源, 它与同一进程的其它线程共享同一份系统资源, 同一进程中的多个线程可以并发执行.

线程的特点

  • 线程是轻量级进程.
  • 同一个进程中的多个线程共享同一份系统资源. (创建线程就省去了申请资源的开销, 销毁线程也省去了释放资源的开销)
  • 每个线程, 都是一个独立的执行流, 可以独自参与到 cpu 的调度.
  • 当有多个线程的时候, 这些线程的执行顺序是不确定的, 因为操作系统中, 有一个 "调度器" 模块, 这个模块的调度方式, 是类似于 "随机调度" 的.

2. 进程与线程之间的区别(重点)

  • 一个进程包含多个线程.
  • 每个线程, 是一个独立的执行流, 可以执行一些代码, 并且单独参与到 cpu 的调度中
  • 每个进程有自己的资源, 进程中的线程共享同一份资源 (内存 + 文件描述符表)
  • 进程和进程之间, 不会相互影响, 如果同一进程中的某个线程抛出异常, 可能会影响其他线程, 会把整个进程中的所有线程都异常终止.
  • 线程上下文切换比进程上下文切换要快得多。
  • 同一进程中的线程之间, 可能会相互干扰, 引起线程安全问题.
  • 线程也不是越多越好, 要能够合适, 如果线程过多, 调度开销可能会非常明显.

3. 创建线程

run方法是线程的入口.

调用start() 之后, 才是启动线程, 这时此线程处于就绪(可运行)状态.

class MyThread1 extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("hello Thread");
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread1 t = new MyThread1();
        t.start();
        while(true){
            System.out.println("hello main");
        }
    }
}

代码执行以后, 就是不断循环打印hello main和 hello Thread.

如果是单线程, 就只能执行一个死循环, 而现在, 两个循环都能执行, 这就是并发.

lambda 表达式

创建线程的方法, 最常用也是最推荐的方法就是 lambda 表达式. 

public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();//调用start才会创建线程
    }
}

我们代码创建的线程, 默认是前台线程, 会阻止进程结束, 只要前台进程不结束, 进程就不会结束, 即使 main 线程已经执行完毕.

使用setDaemon(), 设为true 是后台, 不设为true 是前台.

public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable(){
            @Override
            public void run() {
                while(true){
                    System.out.println("hello thread");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"这是我的线程");
        //代码创建的线程默认是前台线程, 阻止进程结束
        //在start之前设置成后台线程,不能在start之后设置
        t.setDaemon(true);
        t.start();
    }
}

isAlive()

表示了, 内核中的线程(PCB) 是否还存在.

Java 代码中定义的线程对象实例, 虽然表示一个线程, 但这个对象的生命周期, 和内核中的PCB生命周期是完全不一样的.

此时 t 对象有了, 但内核PCB还没有, 此时 isAlive 就是false.

t.start() 才在内核中真正创建出PCB, 此时isAlive 就是true.

当线程 run 执行完了, 此时内核中的线程也就结束了, 内核中的PCB也就释放了,

但此时 t 变量可能还存在, 但 isAlive 也是false.

好啦, 我们下个文章见~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值