Java多线程精讲:进程和线程介绍

更新时间:2021-08-26 16:24:08 点击次数:749次
1.1 线程相关概念
进程:
      进程(process)是计算机中的程序关于某数据集合一次运行活动,是操作系统进行资源分配和调度的基本单位。
        可以把进程简单理解为操作系统中正在运行的一个程序。
线程:
        线程(Thread)是进程的一个执行单元。
        一个线程是进程中一个单一顺序的控制流,进程的一个执行分支。
        进程是线程的容器,一个进程至少有一个线程。
        在操作系统中,进程是分配资源的基本单位,如虚拟存储空间、文件描述符等。在进程中,每个线程都有各自的线程栈,自己的寄存器环境,自己的线程本地存储。
主线程和子线程:
       JVM启动时会创建一个主线程,该主线程负责执行main方法。主线程就是执行main方法的线程。
       JAVA中的线程不是孤立的,线程之间也会存在一些联系。如果A线程创建了B线程,那么A线程就是B线程的父线程,B线程就是A线程的子线程。
 1.2 串行、并发和并行:
假设有3个任务:A准备5分钟,等待5分钟;B准备2分钟,等待8分钟;C准备10分钟。
串行:sequential,所有任务逐个完成
10 + 10 + 10 = 30分钟
并发:concurrent,在任务A等待的过程中,开始做任务B,任务B等待的过程中启动任务C
5 + 2 + 10 = 17分钟
并行:parallel,三个任务同时开始
10分钟
1.3 线程的创建和启动
在Java中,创建一个线程就是创建一个Thread类(或子类)的对象(或称实例)。
Thread类有两个常用的构造方法:
Thread();
Thread(Runnable target);
创建线程的两种方法:
1、继承Thread类,并重写run方法
package createThread.p1;
/**
 * 1、定义Thread类的子类
 */
public class MyThread extends Thread{
    //2、重写Thread类的run方法
    //run()方法体内的内容就是线程要执行的代码
    @Override
    public void run() {
        System.out.println("这是子线程执行的内容");
    }
    public static void main(String[] args) {
        //3、创建线程对象
        MyThread myThread = new MyThread();
        //4、启动线程
        myThread.start();
        /**
         * 调用线程的start()方法来启动线程,启动线程的实质是请求JVM运行相应的线程,这个线程具体什么时候运行,由线程调度器(scheduler)决定
         * 注意:
         *   调用start()方法不代表线程能立马运行
         *   线程启动后会运行run()方法
         *   如果启动了多个线程,start()调用的顺序不一定就是线程启动的顺序
         */
    }
}
2、实现runnable接口来创建线程
package createThread.p2;
//1、继承Runnable接口
public class MyRunable implements Runnable{
    //2、实现run方法
    @Override
    public void run() {
        System.out.println("This is a thread");
    }
    public static void main(String[] args) {
        //3、将实现了Runnable接口的对象传入Thread的构造方法中
        Thread thread = new Thread(new MyRunable());
        //4、启动线程
        thread.start();
    }
}
1.4 线程的常用方法 
1、currentThread()
Java中的任何一段代码,都是运行在某个线程中的。使用如下方法可以获得运行当前代码的线程。
Thread.currentThread()
2、setName()/getName()
通过设置线程名称,有助于程序调试,提高程序的可读性,建议为每个线程设置一个名称。
thread.setName(线程名称);  //设置线程名称
thread.getName();         //获得线程名称
3、isAlive
判断线程是否处于活动状态(只要启动了,然后还没终止,那就是活着的线程)
thread.isAlive();
4、sleep
让当前线程休眠指定的毫秒数,当前线程指的是Thread.currentThread()返回的线程
Thread.sleep(millis);  //让当前线程休眠指定的毫秒数
TimeUnit.SECONDS.sleep(seconds);  //显示地知道休眠的时间
5、getId
thread.getId() 可以获得线程的唯一标识。
注意:如果某个编号运行结束,该编号可能被后续创建的线程使用。
重启了JVM后,同一个线程的编号可能不同了。
6、yield
Thead.yield():放弃当前的CPU资源,然后由CPU重新进行调度。
7、setPriority
thread.setPriority(num) :设置线程的优先级,num的取值范围是1~10。如果超出这个范围会抛出异常IllegalArgumentException。
在操作系统中,优先级较高的线程获得CPU的机会越多
线程优先级本质上只是给线程调度器一个提示信息,以便于调度器决定先调度哪些线程。注意不能保证让优先级高的线程先运行。
Java优先级设置不当或者滥用,可能会导致某些线程永远无法得到运行,即产生了线程饥饿。
线程的优先级并不是设置得越高越好,一般情况下使用普通的默认的优先级即可。
线程的优先级具有继承性,在A线程中创建了B线程,则B线程的优先级和A线程的优先级是一样的
8、interrupt
调用某一线程的interrupt方法,仅仅是在当前线程打一个停止标志,并不是真正的停止线程。
9、setDaemon
Java中的线程分为用户线程和守护线程
守护线程是为其他县城提供服务的县城,如垃圾回收器(GC)。
守护线程不能单独运行,当Java虚拟机中没有其他用户线程,只有守护线程时,守护线程会自动销毁。

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

回到顶部
嘿,我来帮您!