Java并发编程之美——线程基础(一)

第一章 并发编程线程基础

在学习java web的过程中,思考过这样一个问题,如果仅仅是跟着视频做几个项目,是否有资本找到一个较好的工作,结合师兄和师姐找工作的过程,他们说找工作的话,面试官问的问题都很基础,也就突出了一个问题,对于应届生,在没有什么实战项目经验的情况下,面试过程中对于基础知识的考核将会是一个重点。后来又思考了一个问题,我们跟着视频做的web项目,到底有多少的实用价值?我个人感觉是很少,我想的是,即使这个项目用到了很多的技术,什么redis、dubbo、solr等等,但是当面对庞大的请求或者搜索的时候,以现有项目的状况,绝对会出现崩的状况,那么如何实现高并发就是一个问题,这也是我决定进行高并发学习的一个重要原因,同时在有理论加代码的基础上,考虑把高并发结合到web的项目上。

什么是线程?什么是进程?

进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。

例子:其实我们电脑或者手机上每一个软件都是一个进程,例如qq或者office,那么在qq或者office中有许多的功能,其中的每一个功能都是一个线程,比如视频、信息发送、信息接收等等。

在这里插入图片描述

操作系统在分配资源时把资源分配给进程,但是CPU的资源比较特殊,CPU资源被分配到线程,因为真正要占CPU运行的是线程。

上图中有三种类型区域:堆、方法区和线程。

里面主要存放使用new操作创建的对象实例。

方法区用来存放JVM加载的类、常量以及静态变量等信息。

如上图,在这个进程中,有两个线程,这两个线程共享同一个堆和方法区。同时在每个线程之内有一个程序计数器

那么程序计数器是什么作用呢?我们知道,CPU的执行方式是时间片轮转方式,在当前的线程CPU时间片使用完毕后要让出CPU,那么为了在下次CPU轮到自己时,继续执行上次中断的任务,我们就要记录上次让出CPU时候线程的执行地址,那么程序计数器就起到了存储该线程让出CPU时的执行地址的作用
的作用就是存储该线程的局部变量,还要存储线程的调用栈帧。

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的虚拟机栈的栈元素。
栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。

线程的创建与运行

1. 实现Runnable接口的run方法
public static class RunnableTask implements Runnable{

    @Override
    public void run() {
        System.out.println("I am a child thread");
    }

    public static void main(String[] args){

        //创建线程
        RunnableTask task = new RunnableTask();

        new Thread(task).start();
        new Thread(task).start();

    }
}

在创建完Thread对象之后,该线程并没有立即执行,在调用了start()方法之后,线程并没有立即执行,而是进入就绪状态,就绪状态就是该线程获得了除CPU资源以外的其他资源,等道获取CPU资源之后才真正处于运行状态。

2. 继承Thread类并重写run方法
//继承Thread类并重写run方法
    public static class MyThread extends Thread{

        @Override
        public void run(){

            System.out.println("I am a child thread");

        }

        public static void main(String[] args){

            //创建线程
            MyThread myThread = new MyThread();

            //启动线程
            myThread.start();

        }

    }

由于java不支持多继承,所以如果已经继承了Thread类,那么就不能再继承其它的类,这是继承Thread的一个缺点。但是使用继承的一个好处是容易传参

3.FutureTask方法
public static class CallerTask implements Callable<String>{


    @Override
    public String call() throws Exception {
        return "hello";
    }

    public static void main(String[] args) throws InterruptedException{

        //创建异步任务
        FutureTask<String> futureTask = new FutureTask<>(new CallerTask());

        //启动线程
        new Thread(futureTask).start();

        try {
            String s = futureTask.get();
            System.out.println(s);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

FutureTask的方法可以拿到任务的返回值

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值