进程与线程学习笔记

进程与线程

一、并发与并行

  • 并发∶指两个或多个事件在同一个时间段内发生。

  • 并行 : 指两个或多个事件在同一时刻发生(同时发生)。

二、进程、线程与守护线程

进程∶是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位﹔系统运行一个程序即是一个进程从创建、运行到消亡的过程。

在这里插入图片描述

线程︰线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

在这里插入图片描述

简而言之 : 一个程序运行后至少有一个进程,一个进程中可以包含多个线程。我们可以在电脑底部任务栏,右键----->打开任务管理器,可以查看当前任务的进程︰进程

守护(daemon)线程

  • 线程分为用户线程和守护线程
  • 虚拟机必须确保用户线程执行完毕
  • 虚拟机不用等待守护线程执行完毕。
  • 如,后台记录操作日志,监控内存,垃圾回收等待.

三、创建线程类

1、概要与简单使用

Java使用 java.lang.Thread 类代表 线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。Java中通过继承Thread类来创建并启动多线程,步骤如下∶

1.定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把 run()方法称为线程执行体。

2.创建Thread子类的实例,即创建了线程对象

3.调用线程对象的start( )方法来启动该线程

/**
 * java.Lang. Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类
 * 实现步骤:
 *      1.创建一个Thread类的子类
 *      2.在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
 *      3.创建Thread类的子类对象
 *      4.调用Thread类中的方法start方法,开启新的线程,执行run方法l
 *          void start()使该线程开始执行;Java虚拟机调用该线程的run方法。
 *          结果是两个线程并发地运行;当前线程(main线程)和另一个线程(创建的新线程,执行其run方法)。
 *          多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
 */
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        //非 Thread 类[子类]对象 获取线程名称: 用 Thread类 的 静态方法 currentThread()
        //获取 Thread对象,再使用getName()获取进程名
        System.out.println("线程名称:"+Thread.currentThread().getName());
        for (int i = 0; i < 20; i++) {
            System.out.println("main --> "+i);
        }
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        // Thread 类[子类]对象 获取线程名称,使用成员方法 getName()
        System.out.println("线程名称为:"+getName());
        for (int i = 0; i < 20; i++) {
            System.out.println("run --> "+i);
        }
    }
}

//输出结果(部分) -->随机打印
线程名称:main
线程名称为:Thread-1
线程名称为:Thread-0
main --> 0
run --> 0
main --> 1
run --> 1
run --> 2
  ......
main --> 17
main --> 18
main --> 19

图解解释:在这里插入图片描述

内存图解:

在这里插入图片描述
在这里插入图片描述

2、构造方法与常用方法

在上一天内容中我们已经可以完成最基本的线程开启,那么在我们完成操作过程中用到了java.lang.Thread类,API中该类中定义了有关线程的一些方法,具体如下∶
构造方法

public Thread( )//分配一个新的线程对象。
public Thread( String name)//分配一个指定名字的新的线程对象。
public Thread(Runnable target)//分配一个带有指定目标新的线程对象。
public Thread(Runnable target,string name)//分配一个带有指定目标新的线程对象并指定名字。

常用方法

public String getName()//获取当前线程名称。
public void start()//导致此线程开始执行; Java虚拟机调用此线程的run方法。
public void run()//此线程要执行的任务在此处定义代码。
public static void sleep(long millis)//使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)
public static Thread currentThread()//返回对当前正在执行的线程对象的引用。

翻阅API后得知创建线程的方式总共有两种,一种是继承Thread类方式,一种是实现Runnable接口方式,方式一我们上一天已经完成,接下来讲解方式二实现的方式。

3、实现Runnable接口创建线程

创建多线程程序的第二种方式:实现Runnable接口java.lang. Runnable,Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法java.lang.Thread类的构造方法,

public Thread(Runnable target)//分配一个带有指定目标新的线程对象。
public Thread(Runnable target,string name)//分配一个带有指定目标新的线程对象并指定名字。

实现Runngble接口创建多线程程序的 好处 :

  1.避免了单继承的局限性
       一个类只能继承一个类,类继承了Thread类就不能继承其他的类实现了Runnable接口,还可以继承其他的类,实现其他的接口
  2.增强了程序的扩展性,降低了程序的耦合性(解耦)
      实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦)实现类中,  
      重写了run()方法 : 用来设置线程任务,创建Thread类对象, 调用start()方法 : 用来开启新线程

4、匿名内部类的形式

匿名内部类方式实现线程的创建,匿名 : 没有名字

内部类 : 写在其他类内部的类,

匿名内部类作用 : 简化代码,把子类继承父类,重写父类的方法,创建子类对象合一步完成,把实现类实现类接口,重写接口中的方法,创建实现类对象合成一步完成。

匿名内部类的最终产物 : 子类/实现类对象,而这个类没有名字。

//格式
new 父类/接口(){
	重写父类/接口中的方法
};

//例子
 public static void main(String[] args) {
        // Thread类方式
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println("InnerClassThread --> "+i);
                }
            }
        }.start();
        // Runnable接口方式
        new Thread( new Runnable(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println("InnerClassRunnable --> "+i);
                }
            }
        }).start();
    }

5、使用Callable接口创建线程

例子1,直接运行线程:

public class ThreadByCalable {
    public static void main(String[] args) throws Exception
        
        FutureTask<Integer> futureTask = new FutureTask<>(new MyThreadCallable());
        new Thread(futureTask).start();
        System.out.println("返回值为:"+futureTask.get());
    }
}

class MyThreadCallable implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println("Callable->线程实现");
        return 100;
    }
}

例子2,通过线程池线程:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值