进程和线程详解

8 篇文章 0 订阅

一、进程

1、进程是操作系统分配资源的基本单位,例如:运行的一个程序。
2.进程的组成
(1)PID:进程唯一的身份标识;
(2)状态:
新建状态:刚建立好的状态;
就绪状态:得到资源准备执行;
运行状态:正在运行;
阻塞状态:等待其他资源的停止状态;
销毁状态:进行运行完就被销毁。
转化如图:在这里插入图片描述
(3)优先级:决定进程的执行顺序;
(4)记账信息:记录运行情况,保证进程执行相对公平;
(5)上下文:保存本次的执行状态,以便下次继续执行;
(6)一组内存:进程运行所需要的资源。

*时间片:每个进程得到的CPU执行时间;
*内核态:操作系统作为最底层的软禁拥有的最高权限;
*用户态:指用户编写的程序。

二、线程

1、定义:线程是操作系统进行调度的最小单位,是进程的实际运作单位。一个进程可以包含多个线程,每个线程执行不同的任务。
2、线程的优势:
(1)线程的创建和销毁消耗的资源比进程小很多,效率更高;
(2)线程可以共享资源,如:内存和打开的文件。进程不可以共享。

三、进程VS线程

(1)从属关系不同:
进程中包含线程,而线程中不包含进程。
(2)侧重点不同:
进程是分配资源的最小单位,而线程是操作系统调度的最小单位。
(3)资源共享不同:
进程之间不能共享资源,而线程之间可以共享资源;
(4)上下文切换速度不同:
进程上下文切换速度比较慢,而线程上下文切换速度很快。
(5)操纵者不同:
进程的操纵者是操作系统,而线程的操纵者是编程人员。

*创建的线程是否越多越好呢?
创建线程多少要根据实际服务器硬件配置来定,如果过多可能带不动,也可能会造成线程恶意争抢和过度调度的问题,会降低执行效率。

四、线程的常规操作

1、线程常见的构造方法
(1)Thread():创建线程对象
(2)Thread(Runnable target):使用Runnable对象创建线程;
(3)Thread(String name):为线程对象并命名;
(3)Thread(Runnable target,String name):用R创建线程对象并命名;
(4)Thread(ThreadGroup group,Runnable target):将线程进行分组管理。
2、线程的常用属性
在这里插入图片描述
线程的详细状态请转添加链接描述
3、线程的常用方法
(1)线程等待:join()
等待某一线程执行完后,才能进入下一步工作
join():无参数,无线等待
join(long millis):等待long类型时间长度

public static void main(String[] args) throws ExecutionException, InterruptedException {
        Thread t1=new Thread(()-> {
            System.out.println("张三开始工作");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("张三下班!");
        });

        Thread t2=new Thread(()-> {
            System.out.println("李四开始工作");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("李四下班!");
        });

        t1.start();

        t1.join();
        System.out.println("换班");
        t2.start();
    }

在这里插入图片描述
(2)线程终止:interrupt()
interrupt() : 发起线程中断请求,但只是请求,并不会真的把线程给中断,实际上是把线程的中断标识设置为了true;
isInterrupted():判断线程的中断标识是否为true
interrupted() : 判断线程的中断标识是否为true, 方法调用完之后,会将中断标识改为false

public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
            System.out.println("线程开始执行!");
            while (!Thread.interrupted()){
                System.out.println("线程正在执行!");
            }
            System.out.println("线程执行中断!");
        });

        thread.start();

        Thread.sleep(1);
        thread.interrupt();
        System.out.println("终止!");
    }

在这里插入图片描述
注意:
interrupted()和isInterrupted()的区别:
interrupted()属于静态方法,所有程序都可以直接调用,而isInterrupted()是某个实例的方法。
interrupted()在使用后会重置中断标识符,而isInterrupted()不会重置中断标识符。

(3)让出执行权:yield()
yield():会让出CPU执行权,让线程调度器重新调度线程,但是也不是一味的让,是适当的让,多次调度自己还是会执行。

public static void main(String[] args) {
        Thread t1=new Thread(()->{
            for (int i = 0; i < 100; i++) {
                Thread.yield();
                System.out.println("执行"+Thread.currentThread().getName());
            }
        },"张三");
        Thread t2=new Thread(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("执行"+Thread.currentThread().getName());
            }
        },"李四");

        t1.start();
        t2.start();
    }

在这里插入图片描述
注意:
让线程优先执行的方法:
(1)给这个线程设置高优先级;
(2)让这个线程调度yield()方法。

(4)获得当前线程:currentThread()

public static void main(String[] args) {
        Thread t1=new Thread(()->{
                System.out.println("执行"+Thread.currentThread().getName());
        },"张三");
        t1.start();
    }

在这里插入图片描述
(5)线程休眠的方法
Thread.sleep(参数):有限休眠
在这里插入图片描述

五、线程创建的方法

线程创建一共分为三大类七中方法:
(1)继承Thread进行实现(一种);
(2)实现Runnable接口进行实现(四种);
(3)实现Callable接口进行实现(两种)。
1、继承Thread进行实现

public class MyThread extends Thread{
    @Override
    public void run() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName());
    }
}
public class Test {
    public static void main(String[] args) {
        Thread thread=new MyThread();
        thread.run();
        thread.start();
    }
}

在这里插入图片描述
注意:使用start()和run()都可以启动线程,两者有什么区别?
(1)run()相当于一个普通方法,不开启新线程,而start()是真正开启一个线程来执行任务;
(2)run()为线程体,包含具体执行的业务代码,调用run()会立即执行,而start()是启动一个线程并设为就绪状态,不会立即执行;
(3)run()是普通方法,可以多次调用,而start()是创建线程来回字形任务的,只能创建执行一次。

2、实现Runnable接口进行实现
(1)直接实现Runnable来创建

public class MyThread{
    public static void main(String[] args) {
        //创建Runnable
        Thread1 thread1=new Thread1();
        //创建线程
        Thread thread=new Thread(thread1);
        thread.start();
    }
}
class Thread1 implements Runnable{
    @Override
    public void run() {
        Thread thread=Thread.currentThread();
        System.out.println(thread.getName());
    }
}

在这里插入图片描述
(2)用匿名Runnable创建

public class MyThread{
    public static void main(String[] args) {
        Thread thread=new Thread(new Runnable(){
            @Override
            public void run() {
                Thread thread=Thread.currentThread();
                System.out.println(thread.getName());
            }
        });
        thread.start();
    }
}

在这里插入图片描述
(3)匿名方式创建

public class MyThread{
    public static void main(String[] args) {
        Thread thread=new Thread(){
            @Override
            public void run() {
                Thread thread=Thread.currentThread();
                System.out.println(thread.getName());
            }
        };
        thread.start();
    }
}

在这里插入图片描述
(4)使用Lambda表达式来创建(最推荐使用)

public class MyThread{
    public static void main(String[] args) {
        Thread thread=new Thread(()->{
                Thread t=Thread.currentThread();
                System.out.println(t.getName());

        });
        thread.start();
    }
}

在这里插入图片描述
3、实现Callable接口进行实现(有返回值)
(1)Future+Callable(用Future来接收返回值)


public class MyThread{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建MyCallAble对象
        MyCallable myCallable=new MyCallable();
        FutureTask<Integer> futureTask=new FutureTask<>(myCallable);
        Thread thread=new Thread(futureTask);
        thread.start();
        int result= futureTask.get();
        System.out.println(result);
    }
}
class MyCallable implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        int random=new Random().nextInt(10);
        System.out.println(Thread.currentThread().getName()+"随机数"+random);
        return random;
    }
}

在这里插入图片描述
(2)匿名Callable实现

public class MyThread{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask=new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int random=new Random().nextInt(10);
                System.out.println(Thread.currentThread().getName()+"随机数"+random);
                return random;
            }
        });
        Thread thread=new Thread(futureTask);
        thread.start();
        int result= futureTask.get();
        System.out.println(result);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值