java-多线程基础1

一、进程和线程的关系

什么是进程:我们可以任意正在执行的app看成一个进程,进程是操作系统中资源分分配调度的基本单位,进程是拥有自己的地址空间的,进程中至少有一条线程,线程共享着进程的地址空间,可以把进程看成线程的容器。

什么是线程:是指在java程序中同时执行多个任务的机制,每个线程都是独立的执行路径,可以同时执行不同的任务或者处理不同的数据。在多线程中,每个线程都有自己的程序计数器、堆栈和局部变量,但是它们共享进程的虚拟地址空间、全局变量和静态变量。多线程是把双刃剑,多线程的使用可以提高程序的并发性和效率,但是利用的不恰当程序就会面临未知异常甚至是程序崩溃。

深挖概念:

①程序计数器:是用于存储线程执行的下一条指令地址。每个线程都有自己的程序计数器,用于记录线程当前执行的位置。

②堆栈:是用于存储方法调用和返回的数据、参数和局部变量空间。在线程中,每个线程都有自己的堆栈,用于存储线程执行过程中的数据。

由于每个线程都有自己的计数器、堆栈和局部变量,因此线程之间是相互独立的。

二、线程的启动

我们熟悉的有两种启动线程的方式:

  1. 实现Runnable 接口。

  1. 继承Thread类,重写run方法。

在这里我们通常使用第一种启动线程的方法,因为在java中只能单继承,如果使用第二种,则占用的继承名额,使得程序的扩展性降低。

代码实现:

public class MyRunnable implements Runnable{//实现Runnable接口
    @Override
    public void run() {
        System.out.println("我们开始执行任务。。。。。。");
    }
public static class MyTest {
        public static void main(String[] args) {
            MyRunnable mr = new MyRunnable();
            new Thread(mr).start();
        }
    }
}

我们在使用第一种方法创建线程,也就是实现Runnable接口,可以把这个实现Runnable接口的类当成一个任务,我们需要启动线程就必须创建Thread类对象,把任务传入,调用start方法,成功启动线程。

public class ThreadStart {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}
class MyThread extends Thread{//继承Thread类
    @Override
    public void run() {
        System.out.println("线程启动。。。");
    }
}

在这里我们得注意一个点,当程序执行start方法的顺序并不代表程序启动的顺序。

package pgs0325;

public class ThreadText {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyThread(1));
        Thread t2 = new Thread(new MyThread(2));
        Thread t3 = new Thread(new MyThread(3));
        Thread t4 = new Thread(new MyThread(4));
        Thread t5 = new Thread(new MyThread(5));
        Thread t6 = new Thread(new MyThread(6));
        Thread t7 = new Thread(new MyThread(7));
        Thread t8 = new Thread(new MyThread(8));
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
    }
}
class MyThread implements Runnable{
    private int no;
    public MyThread(int no){
        this.no = no;
    }

    @Override
    public void run() {
        System.out.println(no);
    }
}

输出结果不是预期 1 2 3 4 5 6 7 8。

为什么会这样呢?这主要是因为任务的执行靠CPU,而处理器采用分片轮询方式执行任务,所有的任务都是抢占式执行模式,也就是说任务是不排序的。可以设置优先级,优先级高的任务可以会优先执行(多数是无效的)。任务被执行前,该线程处于自旋等待状态。

那什么是CPU时间分片?时间分片是指操作系统将CPU时间分为多个时间片,每个时间片分配给一个任务使用,任务在时间片结束前执行完毕或自行放弃CPU的使用,然后CPU将时间片分配给下一个任务。

什么是轮询?轮询是指操作系统按照一定的顺序依次轮流分配时间片给各个任务,从而实现任务的并发执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值