进程和线程,线程实现的几种基本方法

 什么是进程?


  我们这里学习进程是为了后面的线程做铺垫的。

一个程序运行起来,在操作系统中,就会出现对应的进程。简单的来说,一个进程就是跑起来的应用程序。

在电脑上我们可以通过任务管理器可以看到,跑起来的应用程序有哪些,同时也是每一个的进程。


在操作系统中,我们常常使用PCB这样的结构体来描述进程,pcb中包含了许多重要的信息,此处不做过多的讨论。

在pcb中最核心的就是,其中包括了很多的内存指针,该指针,会根据操作系统的操作来指向所要进行的资源。

如图:

上图就是,关于操作系统的流程(cpu,pcb,硬件等)。


在一个cpu中包括了很多的核心,一个核心只能进行一个进程。一个核心在不同的时刻可以进行不同的进程。

在这里pcb也提供许多的属性。

1.状态

  就绪状态:就如同生活中随叫随到的这种状态,称为就绪状态。

  阻塞状态:简单来说就是发生了阻塞,不能及时使用。

2.优先级

  优先级:对一个程序的资源分配不均衡,消耗的时间有多有少,这种存在优先级的。

3.上下文

  上下文:这里的上下文就如同字面的意思,上下要对应,不能逻辑不通。

4.记账信息

  记账信息:这里延续了上面的优先级,因为分配资源的问题,我们这里要用表格来记录。

以上的几种属性就是pcb支持进程调度的几种属性。


线程的叙述和在idea上的实现方法


  我们这里引入线程就是为了解决,进程创建开销比较大的问题。

  线程开销比较小,会省很大的成本。

  一个进程包括了多个线程。一个cpu的核可以运行多个线程。

线程具有并行和并发两种特性。

  并行:就是指同一时刻可以进行多个任务。

  并发:就是指不同的线程可以同时进行。


线程的实现


第一种方法:自己写一个类继承Thread类,重写run方法。

如代码:

​package thread;
class MyThread extends Thread{
    @Override
    public void run() {
        for(int i = 0; i < 100; i++){
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Deom1{
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
        for (int j = 0; j < 100; j++){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
​

如代码我们可以看到,上面有两个打印,我们来看一下效果。

如图:

我们可以看到,上面的结果打印是间断的不是连续的,所以这里可以说明,线程是并发执行的。

这上面的run方法就是该线程要执行的东西。


第二种方法:实现Runnable 。

如代码:

package thread;
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 100; i++){
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Dome2 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start();
        for (int j = 0; j < 100; j++){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

这里的结果和上面的结果是一样的。

这里在实列t对象的时候,直接new的一个Thread ,里面又new的自己写的类,这样实现的,这个接口里面,包含了Thread的run方法。


第三种方法:运用匿名内部类

如代码:

package thread;

public class Deom3 {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                for(int i = 0; i < 100; i++){
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
        for (int j = 0; j < 100; j++){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

这里呢我们new的Thread相当于一个匿名的子类。

重写了run方法。

其运行的结果和第一种是一样的。


第四种方法:lambda表达式

如代码:

package thread;

public class Deome4 {
    public static void main(String[] args) {
        Thread t = new Thread(()-> {
                for(int i = 0; i < 100; i++){
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
        });
        t.start();
        for (int j = 0; j < 100; j++){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

这里的lambda表达式,就相当于一个匿名的函数,用完就丢,平替了重写的run方法。

其运行结果和第一种一样。


在这所有的方法上面我们都使用了sleep方法,目的是让打印速度减慢,可以看到并发的效果。

以上就是线程的几种的实现方法。后面还会学习其他的。

相关推荐

  1. C++多线方法

    2024-03-25 20:40:03       7 阅读
  2. QT 创建线方法

    2024-03-25 20:40:03       30 阅读
  3. 创建线方式,及线生命周期?

    2024-03-25 20:40:03       14 阅读
  4. c++ 线状态

    2024-03-25 20:40:03       17 阅读
  5. 进程线

    2024-03-25 20:40:03       7 阅读
  6. 线进程区别及基础线创建

    2024-03-25 20:40:03       34 阅读
  7. 进程线区别

    2024-03-25 20:40:03       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-25 20:40:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-25 20:40:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-25 20:40:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-25 20:40:03       20 阅读

热门阅读

  1. 2024.03.10 校招 实习 内推 面经

    2024-03-25 20:40:03       20 阅读
  2. 【Node.js】流

    2024-03-25 20:40:03       20 阅读
  3. 【如何解决Go包中循环依赖】

    2024-03-25 20:40:03       18 阅读
  4. Android基础面试题目汇总

    2024-03-25 20:40:03       17 阅读
  5. 2019南京大学计算机考研复试机试题-Stepping Numbers

    2024-03-25 20:40:03       15 阅读