一、线程与进程

1、进程:

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

2、线程:

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

也就是说,一个软件中至少有一个应用程序,应用程序的一次运行就是一个进程,一个进程中至少有一个线程。


二、并发与并行

1、并行:

指两个或多个事件在同一时刻发生(同时发生)。指在同一时刻,有多条指令在多个处理器上同时执行。

2、并发:

指两个或多个事件在同一时间段内发生。指在同一个时刻只能有一条指令执行,但多个进程的指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。例如:抢票、电商秒杀


三、线程调度

1、分时调度:

所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。

2、抢占式调度:

优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)。Java使用的为抢占式调度。


四、线程状态的方法

1、休眠:sleep()

2、让步:yield()

3、插队:join()


(一)线程休眠

1、测试类(新年倒计时):

调用Thread.sleep(),方法时,要捕获异常。

括号内部是放的类型是整数,表示休眠的毫秒数。1000毫秒 = 1秒。


//2022.7.29
public class ThreadMethod3 {
    public static void main(String[] args) {
        //新年倒计时中,使用线程休眠的方法
        System.out.println("新年倒计时,开始");
        //使用for循环,进行倒计时
        for (int i = 10; i >=1; i--) {
            System.out.println(i);
            //输出一个数时,暂停一秒
            /*这个sleep休眠方式会出现异常,在主程序中不建议抛出异常
            * 主程序尽可能使用try...catch
            * */
            //选中要放入try内部的代码,按快捷键“Ctrl+Alt+t”,选择try...catch
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("新年快乐");
    }
}

线程休眠测试结果:

java中是一个线程对应一个内核线程吗 线程是java程序的并行机制_开发语言

结果表明:数字每隔一秒才会出现。


 (二)线程让步

1、测试类:

(1)自定义的线程使用匿名内部类创建,重写父类Thread的run()方法。

(2)主函数中创建了另一个线程,在其中调用线程的让步方法Thread.currentThread().yield();


//2022.7.29
public class ThreadMethod4 {
    public static void main(String[] args) {
        //测试线程中的yield方法
        //先自定义一个线程,使用匿名内部类,用Thread类的对象进行接收
        Thread t = new Thread(new Runnable() {
            @Override
            //重写run方法
            public void run() {
                //输出0-20内的偶数
                for (int i = 0; i <= 20; i += 2) {
                    //输出当前线程对象的名称与偶数值
                    System.out.println("当前线程对象的名称" + Thread.currentThread().getName()
                            + ",偶数线程:" + i);
                }
            }
        });
        //启动线程
        t.start();

        //在设置一个主函数的线程,用于打印0-20内的奇数值
        for (int i = 1; i <= 20; i += 2) {
            System.out.println("奇数线程:" + i);
            //此处测试线程状态方法yield()
            //作用是让当前线程暂停一下,当前线程暂停一下,让出CPU,下次两个线程任然使用抢占式调度获得CPU的使用权
            Thread.currentThread().yield();

        }
    }
}

线程让步测试结果:

java中是一个线程对应一个内核线程吗 线程是java程序的并行机制_java_02

 结果表明:线程让步yield(),使当前的线程暂停一下,让出CPU,但是下一次CPU还是可能会调用它。


 (三)线程插队

1、测试类:

(1)自定义的线程使用匿名内部类创建,重写父类Thread的run()方法。

(2)主函数中创建了另一个线程,在其中调用线程的插队方法,此时调用插队方法的对象是先执行线程的对象,如:t.join();

(3)调用插队方法时,需要捕获异常。

(4)异常:

①产生异常时,可使用采用的解决方式是:try...catch(异常类型 变量名)..finilly...或throws

②若try中没有异常,那么catch中的代码不会执行,但finilly中的代码会执行。若try中的代码发生异常,那么catch中进行异常捕获,可使用多个catch。


//2022.7.29
public class ThreadMethod5 {
    public static void main(String[] args) {
        //测试线程状态方法的join()方法
        //先自定义一个线程,使用匿名内部类,用Thread类的对象进行接收
        Thread t = new Thread(new Runnable() {
            @Override
            //重写run方法
            public void run() {
                //输出0-20内的偶数
                for (int i = 0; i <= 20; i += 2) {
                    //输出当前线程对象的名称与偶数值
                    System.out.println("偶数线程:" + i);
                }
            }
        });
        //启动线程
        t.start();

        //在设置一个主函数的线程,用于打印0-20内的奇数值
        for (int i = 1; i <= 20; i += 2) {
            //当i=3时,测试join()方法
            if(i == 3){
                //join()使这个线程停止,执行其他线程完成后再继续
                //直接调用join()方法,会报错,需要捕获异常
                try {
                    //注意:此处调用join()方法的对象,是先要执行的线程对象
                    t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("main:" + i);


        }
    }
}

线程插队测试结果:

java中是一个线程对应一个内核线程吗 线程是java程序的并行机制_多线程_03

 结果表明,插队join()方法调用后,当符合判断条件时,会先执行另一个线程,等待另一个线程执行结束后,才会再次执行原来的线程。