进程与线程(一)

进程

概念:

  • 程序中的一次执行过程,也是系统运行程序的基本单位,因此进程是动态的。
  • 在Java中,当我们启动main函数时其实已经启动了一个JVM的进程,因此我们创建的main就是所在这个进程中的一个线程,也称为主线程

线程

概念

  • 线程是一个程序内部的顺序控制流
  • 线程与进程相似,是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。

生命周期:

在这里插入图片描述

  • 新建状态: 一个新产生的线程从新状态开始了它的生命周期。它保持这个状态直到程序start这个线程。

  • **就绪状态:**当一个线程等待另外一个线程执行一个任务的时候,该线程就进入就绪状态。当另一个线程给就绪状态的线程发送信号时,该线程才重新切换到运行状态。

  • **运行状态:**当一个新状态的线程被start以后,线程就变成可运行状态,一个线程在此状态下被认为是开始执行其任务

  • 休眠状态: 由于一个线程的时间片用完了,该线程从运行状态进入休眠状态。当时间间隔到期或者等待的事件发生了,该状态的线程切换到运行状态。

  • 终止状态: 一个运行状态的线程完成任务或者其他终止条件发生,该线程就切换到终止状态。

线程与进程的区别

  • 每个线程都有独立的代码和数据空间(进程上下文),进程之间的切换会有较大的开销。
  • 线程可以看作轻量级进程,同一类的线程共享代码与数据空间,每个线程都有独立运行虚拟栈程序计数器(PC),由此可见线程切换开销更小。
  • 多进程:在操作系统中同时运行多个任务(程序)。
  • 多线程:在同一个应用程序中有多个顺序流同时执行。

线程的实现方法

  1. Java线程是通过 java.lang.Thread 类实现的,因此可以通过创建Thread实例或继承Thread类来创建新的线程。
/**
 * 通过继承Thread类来创建线程
 * @author Juniors
 */
public class TestThreadInit1 {

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
    
    static class MyThread extends Thread{

        @Override
        public void run() {
            System.out.println("Thread body");
        }
    }
}
  1. 通过实现Runnable接口,并实现接口的run()方法,再用实现Runnable接口的对象作为参数实例化该Thread对象。
/**
 * 通过实现Runnable接口创建线程
 * @author Juniors
 */
public class TestThreadInit2 {

    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }

    static class MyRunnable implements Runnable{

        @Override
        public void run() {
            System.out.println("RunnableThread body");
        }
    }
}
  1. 实现Callable接口,重写call()方法。
  • Callable接口实际属于Executor框架中的功能类,Callable接口与Runnable接口的功能类似,但提供了比Runnable更强大的功能,主要体现以下三点:
    1* :Callable可以在任务结束后提供一个返回值,但Runnable无法提供这个功能。
    2* :Callable中的call()方法可以抛出异常,而Runnable中run()方法不能抛出异常。
    3* :运行Callable可以拿到一个Future对象,该对象可以表示异步计算的结果,他提供了检查计算是否完成的方法。由于线程属于异步计算模型,因此无法从别的线程中得到函数的返回值,在这种情况下,就可以使用Future来监视目标线程调用call()方法的情况,当调用Future的get()方法以获取结果时,当前线程就会阻塞,直到call()方法结束返回结果。
public class TestThreadInit3 {
    
    public static class CallableTest implements Callable<String>{

        @Override
        public String call() throws Exception {
            return "Hello Juniors!";
        }

        public static void main(String[] args) {
            ExecutorService threadPool = Executors.newSingleThreadExecutor();
            //启动线程
            Future<String> future = threadPool.submit(new CallableTest());
                try {
                    System.out.println("waiting thread to finish");
                    //等待线程结束,并获取返回结果
                    System.out.println(future.get());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

三种创建线程方法比较与推荐
以上三种方式中,前两种方式线程执行完后没有返回值,只有最后一种带返回值的。
当需要实现多线程时,一般推荐实现Runnable接口的方式,原因是:通常一个类仅在他们需要被加强或修改时才会被继承,因为Java仅支持单继承。

run()方法与start()方法有什么区别?

  • 通常系统调用线程类的start()方法启动一个线程,此时该线程处于就绪状态,而非运行状态,也就意味着这个线程可以被JVM调度执行。在调度的过程中,JVM调用线程类中的run()方法来完成实际操作,当run()方法结束后,此线程就会终止。
  • 如果直接调用线程类的run方法,则会当作一个普通函数的调用,程序中仍然只有主线程这一个线程。也就是说start()方法可以异步调用run()方法,但是直接调用run()方法却是同步的,因此也就无法达到实现多线程的目的。

start()方法的使用实例:

/**
 * 方法调用 与 线程启动 的区别
 * start()方法的使用
 * @author Juniors
 */
public class TestThreadInit1 {

    public static void main(String[] args) {

        Runner runner = new Runner();
        //runner.run();
        Thread thread = new Thread(runner);
        thread.start();

        for(int i = 1;i < 10;i++){
            System.out.println("Main----"+i);
        }
    }

    static class Runner implements Runnable{

        @Override
        public void run() {
            for(int i = 1;i < 5;i++){
                System.out.println("Runner----"+i);
            }
        }
    }
}

程序运行结果:
在这里插入图片描述
run()方法使用实例:

/**
 * 方法调用 与 线程启动 的区别
 * run()方法使用
 * @author Juniors
 */
public class TestThreadInit1 {

    public static void main(String[] args) {

        Runner runner = new Runner();
        runner.run();
        
        for(int i = 1;i < 10;i++){
            System.out.println("Main----"+i);
        }
    }

    static class Runner implements Runnable{

        @Override
        public void run() {
            for(int i = 1;i < 5;i++){
                System.out.println("Runner----"+i);
            }
        }
    }
}

程序运行结果:
在这里插入图片描述

待更。。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值