【Java】多线程基础

一、进程与线程

1.什么是程序

       程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,可以理解为程序是包含静态代码的文件。例如:浏览器软件、音乐播放器软件等软件的安装目录和文件。

2.什么是进程

       进程是程序的一次执行过程,是系统运行程序的基本单位。在 windows 系统中,每一个正在执行的 exe 文件或后台服务,都是一个进程由操作系统统一管理并分配资源,因此进程是动态的。例如:正在运行中的浏览器就是一个进程。

3.什么是线程

       某些进程内部还需要同时执行多个子任务,我们把子任务称为线程。线程是进程划分成的更小的运行单位
       进程和线程的关系就是:一个进程可以包含一个或多个线程,但至少会有一个主线程。

4.进程与线程的区别

       进程是是程序的一次执行过程,强调资源分配,而线程是进程划分成的更小的运行单位,强调执行过程
       一个进程内包含有多个线程,在执行过程,线程的执行不是线性串行的,而是多条线程并行共同完成。

二、线程的创建方式

       线程的创建只有一种方式,通过Thread创建线程对象,但其对象实现方式有如下四种:

1.方式一:继承 java.lang.Thread 类(线程子类)

// 主线程main
public class MultiThread {
    public static void main(String[] args) {
        //创建并启动子线程
        Thread t = new Thread(new SubThread());
        t.start();
        //主线程继续同时向下执行
        for (int i = 0; i < 100; i++)
            System.out.println("主线程" + i + " ");
    }
}

// 线程执行类
class SubThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程" + i + " ");
        }
    }
}

2.方式二:实现java.lang.Runnable接口(线程执行类)

// 主线程main
public class MultiThread {
    public static void main(String[] args) {
        //创建并启动子线程
        Thread t = new Thread(new SubThread());
        t.start();
        //主线程继续同时向下执行
        for (int i = 0; i < 100; i++)
            System.out.println("主线程" + i + " ");
    }
}

// 线程执行类
class SubThread implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程" + i + " ");
        }
    }
}

3.方式三:实现java.util.concurrent.callable 接口,允许子线程返回结果、抛出异常

// 主线程main
public class MultiThread {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //子线程封装为FutureTask对象,计算1-100的累加和
        SubThread subThread1 = new SubThread(1, 100);
        FutureTask<Integer> task1 = new FutureTask<>(subThread1);

        //子线程封装为FutureTask对象,计算101-200的累加和
        SubThread subThread2 = new SubThread(101, 200);
        FutureTask<Integer> task2 = new FutureTask<>(subThread2);

        // 分别启动两个子线程
        new Thread(task1).start();
        new Thread(task2).start();

        // 分别获取两个子线程的计算结果
        int sum1 = task1.get();
        int sum2 = task2.get();

        // 汇总计算结果
        int total = sum1 + sum2;
        System.out.println(total);
    }
}

// 实现子线程
class SubThread implements Callable<Integer> {
    private int begin, end;

    public SubThread(int begin, int end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    public Integer call() throws Exception {
        int result = 0;
        for (int i = begin; i <= end; i++) {
            result += i;
        }
        return result;
    }
}

4.方式四:线程池

public class MultiThread {
    public static void main(String[] args) {
        // 创建固定大小的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        while (true) {
            //提交多个执行任务至线程池,并执行
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }
}

三、线程的优先级

       在线程中,通过setPriority(int n)设置线程优先级,范围是1-10,默认为 5。
       优先级高的线程被操作系统调度的优先级较高(操作系统对高优先级线程,调度更频繁)。
       注意:并不能代表,通过设置优先级来确保高优先级的线程一定会先执行。

四、总结

  • Java用 Thread 对象表示一个线程,通过调用 start()启动一个新线程
  • 一个线程对象只能调用一次 start()方法;
  • 线程的执行代码写在 run()方法中
  • 线程调度由操作系统决定,程序本身无法决定调度顺序,
  • Thread.sleep()可以把当前线程暂停一段时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值