java基础--笔记13


进程:是一个正在执行的程序。
          每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元。
          线程在控制着进程的执行。

一个进程中至少有一个线程。


创建线程的第一种方式:继承Thread类 
步骤:
1,定义类继承Thread
2,复写Thread类中的run方法
3,调用线程的start方法。该方法两个作用:启动线程,调用run方法。
多线程的一个特性:随机性,谁抢到谁执行,至于执行多长,cpu说了算。

为什么要覆盖run方法呢?
Thread类用于描述线程。该类就定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。

static Thread currentThread() 获取当前线程对象

创建线程的第二种方式:实现Runnable接口
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法(将线程要运行的代码存放在该run方法中)
3,通过Thread类建立线程对象
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数(为什么要将Runnable接口的子类对象传递给Thread的构造函数。因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去执行指定对象的run方法。就必须明确该run方法所属的对象)
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式的区别?
实现方式好处:避免了但继承的局限性
在定义线程时,建议使用实现方式。

两种方式区别:
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类run方法。


进程:正在进行中的程序。代表的是应用程序在内存中的一片空间。也就是一个应用程序在内存在开辟的一个空间。

负责进程中代码执行的称之为:线程(负责运算的)。
一个进程中至少要有一个线程。如果有多个线程,就称之为多线程程序。

系统中多任务同时执行的原理:cpu的快速切换(只有多核才能真正实现)

多线程好处:合理的利用了cpu的资源,让多部分代码同时执行。
弊端:过多的线程会降低效率。

什么时候使用多线程技术?
当需要多部分代码同时执行时,就需要多线程技术了。

如何创建线程?
方式一: 继承Thread类
步骤:1,定义一个类继承Thread类。
          2,重写Thread类中的run方法。将需要让线程执行的任务代码存储到run方法中。
          3,创建Thread类的子类对象(创建一条线程)。
          4,调用Thread类中的start方法,开启线程,并执行run方法中的内容(运行的是Thread子类的run方法)。


理解四步骤的原理:
1,首先,JVM启动时就会有一个执行线程负责main方法的代码,说明每一个执行线程的出现都有自己要执行的代码,这段被线程执行的代码称之为:线程的任务。对于JVM启动的负责执行main方法的线程,称之为主线程(执行主函数代码的线程)。

2,想要创建线程去执行指定的代码。需要自己定义一个线程和主线程实现同时执行。自定义的线程也要有线程的任务。这个任务也要像主线程一样有特定存储的位置。

3,描述线程事物的类是Thread,这个类中有定义存储线程执行任务的位置,这个位置就是run方法。
简单的说,run方法中存放的就是线程的任务代码。
接下来,创建线程并启动线程可以写成这个样子。
创建线程对象   Thread t = new Thread();
开启线程          t.start();开启线程,调用Thread类中的run方法。但是这样做没有意义,因为run方法中并未定义我们需要执行的代码。
那么,我么要执行的代码怎么样才能让自定义的线程来执行呢?
只能把这个代码存储到run方法中,可是Thread类中的run方法我们无法进行修改,只能重写,重写就需要继承。所以需要继承Thread类,并重写run方法,定义线程任务。


每一个线程都有自己的名称来标识。
有一些线程有特定的名称(主线程就叫:main),自定义创建的线程有规律的名称,Thread-编号 ,从0开始。

为了在线程中体现线程的名称:可以通过Thread中的currentThread方法获取当前线程的执行线程对象。
再通过getName获取到当前线程对象的名称。
Thread.currentThread().getName();


面试题:调用run和调用start有什么区别
调用run方法,不开启线程。
调用start方法,开启线程,并让该线程的run方法在新线程中执行。

并发的原理:栈内存中每一个线程都有自己的运行栈空间。

catch (Exception e)
          {
               System.out.println(e.toString());//异常名称+异常信息
               System.out.println(e.getMessage());//异常信息。
               e.printStackTrace();//异常名称+异常信息+异常位置 //jvm默认调用了异常的这个方法进行了默认处理,只不过在此基础上,+ 异常所在的线程。
          }


创建线程的方式二:实现Runnable接口

步骤:
1,定义类实现Runnable接口。
2,重写Runnable接口中run方法。
3,创建Runnable接口中的子类对象。
4,创建Thread类的对象,并将Runnable的子类对象作为参数传递给Thread类的构造函数。
5,调用Thread类中的start方法,开启线程,并执行Runnable接口子类的run方法。


第二种创建线程方式的好处
1,避免了单继承的局限性。
2,将线程任务单独封装成了任务对象,和线程对象进行解耦。(线程对象和任务对象分开单独封装,就如同一条路(线程)上可以跑各种各样的车(任务)。)
建议使用第二种。

面试题:
1,创建线程的两种方式。
2,两种方式的区别。答:第二种方式的好处即可。


为什么要传递Runnable接口的对象?
       实验:不传。编译通过,运行没有结果。
       当调用start时,其实调用的是Thread类中的run方法。而这个run里面并不是我们要执行的线程任务代码。 说明这个线程对象和我们定义的线程任务代码没关系。
目的:将Runnable接口子类对象run方法的线程任务执行。

     定义的线程任务在哪里呢?在Runnable接口的子类run方法中。
     想让线程去执行Runnable接口子类中的run方法,需要将这个线程任务告诉给线程对象。
     怎么告诉呢?线程任务都封装到了run方法中,run方法需要被对象(Runnable接口的子类对象)调用,
     只需要将这个子类对象传递给线程对象即可。传递给构造函数的原因是因为线程对象一创建就需要有指定的任务,可以通过构造函数去实现。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值