排序算法、异常、多线程基础

排序算法、异常、多线程基础

今日内容

  • 冒泡排序
  • 选择排序
  • 二分查找
  • 异常处理
    • throw、throws
    • Objects
    • try…catch…finally
  • 多线程基础
    • 进程与xianc
    • 并发与并行
    • 线程里的方法
    • 多线程的两种实现方法

第一章 冒泡排序(大数到后面)

1.概念

一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的 数据进行操作,直至所有数据按要求完成排序

如果有n个数据进行排序,总共需要比较n-1次.每一次比较完毕,下一次的比较就会少一个数据参与

相邻元素两两比较,如果前面的元素比后面的大,就交换他们,直到数组排序完成

alt

2.实现

import java.util.Arrays;

/*
可以将数组中的内容按照顺序排列
数组:[4,3,2,1]排序之后:[1,2,3,4]
*/
public class Demo01Sort {
public static void main(String[] args) {
// 创建数组
int[] arr = {4, 3, 2, 1};
// 冒泡排序
for (int i = 0; i < arr.length - 1; i++) {

//第一轮...
for (int j = 0; j < arr.length - 1 - i; j++) {
// 我们把前面数的索引看出i后面的看成i+1
// 让索引为i的元素和索引为i+1的元素进行比较,如果前面的元素比后面元素大,就交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;

}
}
System.out.println(Arrays.toString(arr));
// [1, 2, 3, 4]
}
}

第二章 选择排序(小数到前面)

1.概念

​ 选中数组的某个元素,其后面的元素依次和选中的元素进行两两比较,将较大的数据放 在后面,依次从前到后选中每个元素,直至所有数据按要求完成排序 如果有n个数据进行排序,总共需要比较n-1次.每一次比较完毕,下一次的比较就会少一个数据参与.

alt

2.实现

import java.util.Arrays;

/*
选择排序
*/
public class Demo02Sort {
public static void main(String[] args) {
// 定义一个数组
int[] arr = {4, 3, 2, 1};
// 选择排序
for (int i = 0; i < arr.length - 1; i++) {
// 内层循环
for (int i1 = i + 1; i1 < arr.length; i1++) {
// 比后面的大就交换
if (arr[i] > arr[i1]) {
int temp = arr[i];
arr[i] = arr[i1];
arr[i1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}

3.排序的方法

int[] arr1 = {4, 3, 2, 1};
Arrays.sort(arr1);//JDK8以及之后,用的是归并排序算法。 8.之前是快速排序

第三章 二分查找

1.概念

普通查找

原理:遍历数组,获取每一个元素,然后判断当前遍历的元素是否和要查找的元素相同,如果相同就返回该元素的 索引。如果没有找到,就返回一个负数作为标识(一般是-1)
二分查找

原理: 每一次都去获取数组的中间索引所对应的元素,然后和要查找的元素进行比对,如果相同就返回索引; 如果不相同,就比较中间元素和要查找的元素的值;
如果中间元素的值大于要查找的元素,说明要查找的元素在左侧,那么就从左侧按照上述思想继续查询(忽略右侧 数据);
如果中间元素的值小于要查找的元素,说明要查找的元素在右侧,那么就从右侧按照上述思想继续查询(忽略左侧 数据);二分查找对数组是有要求的,数组必须已经排好序

alt

2.实现

System.out.println(Arrays.binarySearch(arr, 85));
public class Demo01Search {
public static void main(String[] args) {
// 定义有序数组
int[] arr = {2,45,67,78,82,85,99};
// 调用二分查找的方法,查找 82
System.out.println("82的索引为:"+binarySearch(arr, 82));
}
/*
定义方法,该方法用来进行二分查找,查找某个元素在数组中的素引。
参数:int[]arr【要在哪个数组中查找】,int value【要查找的元素】
返回值:int【查找出的读元素的索引】
注意,不存在返回-1
*/
public static int binarySearch(int[] arr,int value){
// 定义两个遍历表示光标,一个指向数组的左边一个指向右边
int left = 0;
int right = arr.length-1;
int mid = 0;
//循环执行,进行二分查找
while (left<=right){
mid = (left+right)/2;
if (value > arr[mid])
left = mid + 1;
else if(value < arr[mid])
right = mid - 1;
else
return mid;
}
//if (left>right)
return -1;
}
}

第四章 异常

1.概念

异常指的是不正常,指的是程序出现了某些问题。
在Java中,所有的问题都可以使用一个类来表示,这个类叫做Throwable。
Throwabld是所有错误和异常的父类。

Throwable
/--Exception:异常,程序中轻微的,可以挽回的问题。
/--Error:错误,程序中严重的,不可挽回的问题。

语法错误不是错误与异常

alt

2.异常的产生

/*
异常产生的过程
异常一旦抛出,程序就停止


当程序执行到getValue方法中的arr[index],因为我们传递索引是10,所以系统发现数组中井
没有索引为10的元素,所以这样不合法,于是就在这个位置创建一个异常对象
new ArraylndexOutOfBoundsException0,因为在getValue方法中没有解决异常,那么这个异
常会向外抛(扔),将该异常抛给自己的调用者位置。

main方法也没有解决这个异常,所以main方法拿到异常之后,会继续向外抛,抛给自己的调用者,main方法是JVM调用的

jvm拿到异常对象之后会做两件事情
a.将异常信息输出到控制台。
b.停止程序。
*/
public class Demo02Exception {
public static void main(String[] args) {
int[] arr = {1,2,3,5,2,6,7};
int value = getValue(arr, 10);
//System.out.println(value);
/*
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at cn.com.mryhl.demo03_exception.Demo02Exception.getValue(Demo02Exception.java:14)
at cn.com.mryhl.demo03_exception.Demo02Exception.main(Demo02Exception.java:6)
*/
}
/*
定义方法,该方法获取数组指定素引位置的元素
*/
public static int getValue(int[] arr,int index){
int i = arr[index];
return i;
}

}

第五章 异常的处理

1.抛异常throw

throw:用来手动向外抛出异常
格式:
throw new 异常类名();
使用场景:
如果我们想要手动制造一个问题,就可以用throw关键字,比如年龄录入的是错误的,我们希望程序直接报错,
就可以使用throw关键字手动向外抛出异常

注意:
在创建异常对象时,我们也可以通过在小括号中传递一个字符申类型的异常信息

public class Demo03Throw {
public static void main(String[] args) {
int[] arr = new int[4];
int value = getValue(arr, 10);
System.out.println(value);
}
/*
定义方法,该方法获取数组指定素引位置的元素
*/
public static int getValue(int[] arr,int index){
// 对索引进行一个判断,如果索引不合法,手动抛越界异常
if (index<0||index>=arr.length){
// 手动抛出异常
//throw new ArrayIndexOutOfBoundsException("索引出问题了");
throw new ArrayIndexOutOfBoundsException(index);
}
int i = arr[index];
return i;
}
}

2.Objects判断非空方法

import java.util.Objects;

/*
在objects中,有一个方法可以对对象进行非空判断

static <T> T requireNonNuLL(T obj):判断obj是否是nulL。如果obj是nulL,会引发空指针异常。
*/
public class Demo04Objects {
public static void main(String[] args) {
// 定义Object
Object obj = null;


//使用objects中的requireNonNuLL验证是否为mull
Objects.requireNonNull(obj);
/*if (obj == null){
throw new NullPointerException();
}*/
//通过nuLL调用任何非静态的属性和方法都会引发空指针异常。
obj.toString();
}
}

3.throws声明异常

throw:用来手动向外抛出异常
throws:用来进行异常声明,声明某个方法有可能出现异常,出现问题。


throws格式:
修饰符 返回值类型方法名(参数列表)throws 异常类名{
...
}
throws注意事项:
1.如果在方法中抛出了编译时异常,那么必须要使用throws进行异常声明。
2.如果调用了使用throws声明异常的方法,那么调用者要么使用try...catch解决,要么也要加throws声明。
3.如果在方法中抛出了运行时异常,那么可以加throws声明,也可以不加
4.如果方法中有可能推出多个异常,那么需要进行多异常的声明
5.如果方法中有可能能出多个异常,那么也可以直接声明他们的父类异常
import java.io.IOException;
import java.sql.SQLException;

/*


*/
public class Demo05Throws {
public static void main(String[] args) throws Exception {
method();
}
// 抛出多异常声明
public static void method4() throws Exception {
int num = 10;
if (num%2==0)
throw new IOException();
else
throw new SQLException();
}
// 抛出多异常声明
public static void method2() throws IOException, SQLException {
int num = 10;
if (num%2==0)
throw new IOException();
else
throw new SQLException();
}
// 运行时异常
public static void method1(){
throw new RuntimeException();
}
// 编译异常
public static void method() throws Exception{
// 抛异常
throw new Exception();
}
}

4.try… catch

try...catch 语句
作用: 用来真正解决异常.

格式:
try{
可能出现异常的代码;
}catch(类名 变量名){
出现异常后执行的代码;
}

如果catch小括号中的类名和try中引发的异常一样,那么就表示捕获到了异常。如果捕获到了异常,就表示把异常给解决了。

执行流程:
第一种:如果try中的代码没有异常,那么catch不会执行
第二种:如果try中的代码有异常,并且catch捕获到了这个异常,那么代码会从try直接执行到catch
第三种:如果try中的代码有异常,但是catch没有捕获到这个异常,那么异常会依旧往外抛。


小结:
异常处理有两种方式
向外地(危锅):throw throws
解决异常:try...catch
/*
try catch介绍

*/

public class Demo06TryCatch {
public static void main(String[] args) {
try{
System.out.println("1.try....");
//Object obj = new Object();
/*
1.try....
2.try...
4.main...end
*/
Object obj = null;
/*
1.try....
3.出现异常
4.main...end
*/
obj.toString();
System.out.println("2.try...");
// }catch (NullPointerException e){
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("3.出现异常");
}
System.out.println("4.main...end");
/*
1.try....
Exception in thread "main" java.lang.NullPointerException
at cn.com.mryhl.demo03_exception.Demo06TryCatch.main(Demo06TryCatch.java:36)
*/
}
}

5.finally关键字

try...catch后面可以追加finally代码块
格式:
try{
[A]可能出现异常的代码;
}catch(类名 变量名){
[B]出现异常后执行的代码
} finally{
[c]一定会执行的代码
}
finally代码块的特点:
finally代码块的内容无论如何一定会执行。

执行流程:
第一种情况:如果try中的代码没有异常,执行流程为【A】【C】
第二种情况:如果try中的代码有异常,并且catch辅获到了这个异常,执行流程为【A】【B】【C】
第三种情况:如果try中的代码有异常,但是catch没有描获到这个异常,流程为【A】【C】,抛出异常

finally代码块的使用场景:
一定要执行的代码放在finally代码块中,比如后期释放资源的操作(IO流中的关闭流,JDBC关闭连接)都是在finally代码块中执行的
/*
try...catch后面可以追加finally代码块

*/
public class Demo07Finally {
public static void main(String[] args) {
try {
System.out.println("1.try....");
// Object obj = new Object();//①
Object obj = null;
/*
1.try....
3.catch
4.finall
5.main...end
*/
obj.toString();
System.out.println("2.try...");

// } catch (NullPointerException e) {//①
} catch (ArrayIndexOutOfBoundsException e) {
/*
1.try....
4.finall
Exception in thread "main" java.lang.NullPointerException
at cn.com.mryhl.demo03_exception.Demo07Finally.main(Demo07Finally.java:34)
*/
System.out.println("3.catch");
} finally {
System.out.println("4.finall");
}
System.out.println("5.main...end");
/*①
1.try....
2.try...
4.finall
5.main...end
*/
}
}

6.异常注意事项

6.1编译时异常和运行时异常的区别
import java.io.IOException;

/*
编译时异常和运行时异常的区别
编译时异常:在程序编译时期必须要处理,要么try...catch,要么throws
运行时异常:在程序运行时期,可以处理,也可以不处理。

*/
public class Demo08Exception {
public static void main(String[] args) {
method2();
}
// 运行时异常
public static void method2(){
throw new RuntimeException();
}
/*
Exception in thread "main" java.lang.RuntimeException
at cn.com.mryhl.demo03_exception.Demo08Exception.method2(Demo08Exception.java:17)
at cn.com.mryhl.demo03_exception.Demo08Exception.main(Demo08Exception.java:13)
*/

// 编译时异常
public static void method() throws IOException {
throw new IOException();
}
}
6.2继承关系中方法重写的异常处理
继承关系中方法重写的异常处理
1.如果父类方法没有向外抛出异常,那么子类重写该方法后,也不能向外抛。如果子类方法有异常,只能try...catch
2.如果父类方法向外抛异常,那么子类重写该方法,可以抛,也可以不抛。
如果于类方法向外抛,抛出的异常要么和父类方法异相同,要么是他的子类异常。

注意:上面的异常处理方式,只针对编译时异常,运行时异常不受限制.
import java.io.IOException;

public class Fu {
// 提供方法
public void method(){

}
// 提供方法,该方法对外声明有可能抛出异常
public void function() throws IOException {

}
}
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*


*/
public class Zi extends Fu {
@Override
public void function() throws FileNotFoundException {

}

@Override
public void method() {
//throw new Exception();
String str = "2020-07-06";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = simpleDateFormat.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
6.3多catch异常

try后面可以追加任意个catch
格式:
try{
可能出现异常的代码;
}catch(类名 变量名){
出现异常后执行的代码
}catch(类名 变量名){
出现异常后执行的代码
}catch(类名 变量名){
出现异常后执行的代码
}catch(类名 变量名){
出现异常后执行的代码
}
作用:
用来捕获多种异常

执行流程:
第一种情况:如果try中的代码没有异常,所有的catch都不会执行
第二种情况:如果try中的代码有异常,那么哪个catch先铺获到这个异常,那么就执行哪个catch中的代码。
第三种情况:如果try中的代码有异常,但是所有的catch都没有描获到,那么这个异常会依旧向外地。

注意:如果多catch辅获异常时,父类异常不能放到子类异常的前面

/*



*/
public class Demo09TryCatchCatch {
public static void main(String[] args) {
try {
System.out.println("1.....try Start");
//Object obj = new Object();//1次
Object obj = null;//次
obj.toString();
System.out.println("2.....try end");
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("3...ArrayIndexOutOfBoundsException");
}catch (NullPointerException e){
System.out.println("4...NullPointerException");
}catch (ClassCastException e){
System.out.println("5...ClassCastException");
}catch (Exception e){//3次,后加,注释NullPointerException
System.out.println("6...Exception");
}

System.out.println("7.main end");
}
}
// 1次
/*
1.....try Start
2.....try end
6.main end
*/
// 2次
/*
1.....try Start
4...NullPointerException
6.main end
*/
// 3次
/*1.....try Start
6...Exception
7.main end*/
//4次
/*1.....try Start
4...NullPointerException
7.main end
*/

7.捕获异常方法

在ThrowabLe中,有一些方法,可以获取异常信息。
void printstackTrace():将非常详细的异常信息输出到控制台。(开发过程中推荐)
String getMessage():获取简短异常信息的字符申。(上线后)

Throwable是异常的父类,所以Throwable中的这些方法也可以通过异常对象调用。
我们要先捕获异常,使用捕获到的异常对象调用方法。

/*



*/
public class Demo10ThrowableMethod {
public static void main(String[] args) {
try{
int[] arr =new int[2];
System.out.println(arr[10]);
}catch (ArrayIndexOutOfBoundsException e){
// 变量e就是捕获到的异常对象
//System.out.println(e);
//e.printStackTrace();
//java.lang.ArrayIndexOutOfBoundsException: 10
// at cn.com.mryhl.demo03_exception.Demo10ThrowableMethod.main(Demo10ThrowableMethod.java:16)
String message = e.getMessage();
System.out.println(message);
}
System.out.println("main end");
}
}

第六章 自定义的异常

  • 学生类
public class Student {
private String name;
private int age;

public Student() {
}

public Student(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
  • 定义异常类
/*
自定义异常
如何自定义异常:认赔作父,定义一个类,继承一个异常类即可。

如果一个类继示的是编译时异常,那么该类也就是编译时异常
如果一个类继示的是运行时异常,那么该类也就是运行时异常

我们可以在自定义异常中提供一个构造方法,用来传递异常信息【在该构造方法中要将异常信息交给父类的构造方法】
*/
public class AgeException extends RuntimeException {
public AgeException() {
}

// 提供一个参数为字符串的构造方法,用来给异常信息赋值
public AgeException(String message){
super(message);
}

}
  • 测试类
import java.util.Scanner;

/*

*/
public class Demo01Test {
public static void main(String[] args) {
try{
Student student = createStudent();
System.out.println(student);}
catch (AgeException e){
System.out.println(e);
System.out.println(e.getMessage());
}
catch (Exception e){
System.out.println(e);
}
}
/*
定义一个方法,该方法用来获取一个学生对象,学生的姓名和年龄来源于键盘录入
并且必须保证年龄是正确的,如果年龄是非法的数字,那么我们就抛出异常
*/
public static Student createStudent(){
Scanner scanner = new Scanner(System.in);
System.out.println("键盘录入学生姓名");
String s = scanner.nextLine();
System.out.println("年龄");

// 判断年龄是否合法,非法抛异常
int i = Integer.parseInt(scanner.nextLine());
if (i<0||i>200){
throw new AgeException("年龄不合法");
}


Student student = new Student(s, i);
return student;
}
}

第七章 多线程

1.引入

1.1进程的介绍

正在内存中运行的程序就是进程

1.2线程

程序中的执行单元,每一个线程都可以去做一件事.

如果一个程序只有一个线程,这个程序就是一个单线程程序。
如果一个程序中有多个线程,这个程序就是一个多线程程序。
单线程程序同时只能做一件事情。多线程程序可以同时做多件事情。

一个程序中,至少要有一个线程。

多线程程序可以同时做多件事情.因为多线程程序可以中可以让多给程序同时执行.但是这个同时其实并不是真正意义上的同时,真正意义上的同时是同一个时间点多个线程一起执行,线程是由CPU调度(指挥)才会执行的,同一个时间点,一个CPU只能调度一个线程。

因为CPU可以在多个线程中快速切换,速度非常块,可以看出同时.

抢占式调度:线程抢夺CPU的执行权,哪个线程能够抢到,那么哪个线程就执行,但是哪个线程能抢到,完全是随机的。
上面我们所说的线程抢夺CPU的执行权只是一种通俗的说法,真正主动权在CPU的手里,是CPU看心情确定去调度哪个线程。

从根本上说,是提高cpu的利用率。

2.并发与并行

并发:同一个时间,多个线程一起执行,但是这个同时并不是真正意义上的同时。这个同时可以理解为同一个时间段,多个线程一起执行,因为CPU会在多个线程之间快速切换,因为切换的速度非常快,所以可以看成同时。

并行:同一个时间,多个线程一起执行,这个同时,是真正的同时,是同一个时间点,多个线程一起执行。(多cpu的支持,)

3.main线程

/*
每一个程序都至少包含一个线程,我们写的Java程序也一样。
当我们运行程序时,JVM会创建一个main线程,并执行main方法。

在程序中只有一个执行线程main线程,该程序是单线程程序。
单线程程序同时只能做一件事情,如果想要同时做多件事情,只能向执行一个在执行另一个.

如果想要同时做多件事情,需要使用多线程。
*/
public class Demo01MainThread {
public static void main(String[] args) {
System.out.println("main....start");
//
for (int i = 0; i < 100; i++) {
System.out.println("hello world");
}
//
for (int i = 0; i < 100; i++) {
System.out.println("hello Java");
}
//结束
System.out.println("main....end");
}
}

4.多线程的第一种实现方式

  • 线程类
/*

Thread表示线程类,当使用MyThread继承Thread时,MyThread也就变成了线程类。

*/
public class MyThread extends Thread {
// 重写Thread的run方法
@Override
public void run() {
// 输出100次helloworld
for (int i = 0; i < 10000; i++) {
System.out.println("hello world");
}
}
}
  • 测试类
/*
Java中Thread表示线程,我们可以使用Thread类完成多线程的程序。

多线程的第一种实现方法
1.定义一个类,继承Thread类
2.在子类中重写run方法,并在run方法中定义线程要执行的任务。
3.创建Thread子类对象
4.通过Thread子类对象调用start方法,启动线程。

Thread中的start方法
void start():让线程执行,线程会执行自己的run方法。
void join():等待这个线程死亡。(等线程执行完)
*/
public class Demo02Thread {
public static void main(String[] args) {
// 创建Thread子类对象
// 创建一个新的线程
MyThread myThread = new MyThread();
// 调用start方法,启动线程
// 线程启动,自动调用run方法
myThread.start();
for (int i = 0; i < 10000; i++) {
System.out.println("hello Java");
}

}
}

5.线程里的方法

Thread里的常见的方法
Thread(): 空参数的构造方法
Thread(String name):参数可以传递字符申类型的线程名

Thread中的其他方法
String getName():获取线程名字
void setName(String name):设置线程名字
(记住)static Thread currentThread():获取正在执行的线程对象。
(记住)static void sleep(Long millis):线程休眠,参数是要休眠的喜秒值。

  • Thread类
/*

Thread表示线程类,当使用MyThread继承Thread时,MyThread也就变成了线程类。

*/
public class MyThread extends Thread {


public MyThread() {
}

public MyThread(String name) {
super(name);
}

// 重写Thread的run方法
@Override
public void run() {
System.out.println(getName()+":线程执行了");

}
}
  • 测试类
/*


*/
public class Demo01Thread {
public static void main(String[] args) {
// 创建线程对象
MyThread m = new MyThread();
// 调用方法给线程设置名字
m.setName("何塞荡");
// Thread(String name):参数可以传递字符申类型的线程名
MyThread m1 = new MyThread("舒嘏");
m1.start();
// 线程启动
m.start();
// 获取main线程的名字并输出
// 1.获取当前正在执行的线程对象[该方法通过哪个线程调用执行的,那么获取到的就是哪个线程]
// 因为下面代码是有main线程调用的,获取到的就是main线程对象.
Thread t = Thread.currentThread();

System.out.println("获取的是:"+t.getName());

/* new MyThread().start();
new MyThread().start();
new MyThread().start();*/
/*
Thread-0:线程执行了
Thread-2:线程执行了
Thread-1:线程执行了
Thread-3:线程执行了
*/
}
}
  • sleep
/*
线程体眠的方法
(记住)static void sleep(Long millis):线程休眠,参数是要休眠的毫秒值。
*/
public class Demo02Sleep {
public static void main(String[] args) throws InterruptedException {

System.out.println("开始");
// 线程休眠5000毫秒
Thread.sleep(5000);
System.out.println("结束");
}
}

6.多线程的另一种实现方式

多线程的第二种实现方式
1.定义类实现Runnable接口
2.重写run方法,在run方法中定义线程要执行的任务。
3.创建Runnable接口的实现类对象
4.创建Thread线程对象,将RunnabLe接口的实现类对象作为参数传递。
5.通过线程调用start方法,启动

多线程有两种实现方式
1.继承Thread类
2.实现Runnable接口
推荐第二种:
1.可以解决类与类之间单继示的局限性。
2.可以降低码合性(关联性)
3. Runnable中只有一个run方法,没有getName,sleep,setName,我们只需要在里面关注线程要执行的任务。功能更加纯粹.符合设计模式中的单一职责原则.
4. 更加有利于实现多线程之间数据的共享

  • Runnable的实现类
/*
在java中,Thread类才是线程类.
Task和Thread没有关系,所以Task并不是线程类

Runnable接口中只有一个run方法,run方法中只需要关注线程要执行的任务。Runnable接口只需要关注线程任务即可。
我们也可以把Runnable接口看成线程任务接口
Task实现了Runnable接口,只需要重写run方法,只需要在里面关注线程任务,所以我们可以把Task看成线程任务类。
*/
public class Task implements Runnable {
// 在run方法中定义线程要执行的任务
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("新线程输出hello Java"+i);
}
}
}
  • 测试类
/*

*/
public class Demo01Test {
public static void main(String[] args) {
// 创建Runnable接口的实现类对象
// 创建一个线程任务对象,表示要执行的方法
Task task = new Task();
// 创建线程对象
Thread thread = new Thread(task);// 将创建的线程与线程对象绑定
// 线程启动
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println("main线程在输出hello Java"+i);
}
}
}

7.匿名内部类实现多线程

/*
匿名内部类实现多线程

匿名内部类格式:
new 父类或接口(){
重写方法
}
作用:
创建某个类(接口)的子类(实现类)对象
举例:
new Person(){
重写的防法
}
创建了一个Person的子类对象,但是这个子类叫什么我们不知道。

*/
public class Demo01Test {
public static void main(String[] args) {
/*// 创建Runnable接口的实现类
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "匿名内部类执行了");
}
};
// 创建线程,传递Runnable接口的实现类,并启动线程
new Thread(r).start();
*/

/*new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "匿名内部类执行了");
}
}).start();*/
new Thread(() -> System.out.println(Thread.currentThread().getName() + "匿名内部类执行了")).start();
}
}

总结

一. 冒泡排序
选择排序
二分查找。

理解里面的思想。

二. 异常

体系
Throwable:所有异常和错误的父类
|-- Error:错误:程序中不可挽回的严重问题
|-- Exception:异常:程序中可以挽回的轻微问题。

异常的分类:
运行时异常:RuntimeException以及他下面的所有子类
编译时异常:Exception以及除了RuntimeException之外的其他子类。

throw关键字:
作用:用来手动抛出异常
格式:
throw new 异常类型();

throws关键字:
作用:用来进行异常声明,声明某个方法有可能会抛出异常。

格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类名{
...
}
try...catch
作用:用来解决异常
格式:
try {
可能出现异常的代码
} catch(异常类名 变量名) {
出现异常后执行的代码;
}
执行流程:
如果try中的代码没有问题,会跳过catch
如果try中的代码有问题,并且catch捕获到了这个异常,代码会从try执行到catch
如果try中的代码有问题,但是catch没有捕获到这个异常,异常会往外抛


finally
try...catch后面可以追加finally代码块,
作用:
finally代码块的内容无论如何肯定会执行。


catch处理异常:
格式:
try {
可能出现异常的代码
} catch(异常类名 变量名) {
出现异常后执行的代码;
} catch(异常类名 变量名) {
出现异常后执行的代码;
}
执行:
如果try中的代码有问题,哪个catch先捕获到,那么就执行哪个catch中的语句。
如果try中的代码没有问题,所有catch都不会执行。

注意:
在多catch异常处理时,父类不能放到前面。

运行时异常和编译时异常的区别
编译时异常:在程序编译时期必须要处理,要么try catch,要么throws
运行时异常:在程序编译时期必须可以处理,也可以不处理。

继承中异常的注意:
如果父类方法没有抛异常,子类重写该方法也不能抛。

自定义异常
如果要自己定义异常,直接定义一个类,去继承异常类即可。如果继承的是编译时异常,该异常也就是编译时
异常,如果继承的是运行时异常,那么该异常也就是运行时异常。


多线程
线程和进程
进程:正在内存中运行的程序
线程:程序中的执行单元(执行任务的单位),每一个线程都可以执行一个任务。

并发和并行:
并发:同一个时间段多个线程一起执行。
并行:同一个时间点多个线程一起执行。

多线程第一种实现方式(继承Thread类)
1. 定义类,继承Thread
2. 重写run方法,在run方法中定义线程要执行的任务。
3. 创建Thread子类对象。
4. 通过Thread子类对象调用start方法启动线程。

多线程第二种实现方式(实现Runnable接口)
1. 定义类,实现Runnable接口
2. 重写run方法,在run方法中定义线程要执行的任务。
3. 创建Runnable实现类对象
4. 创建Thread对象,在构造方法中传递Runnable实现类对象。
5. 调用start方法启动线程。

Thread的方法:
Thread中的构造方法
Thread():空参数的构造方法。
Thread(String name):参数可以传递字符串类型的线程名。

Thread中的其他方法:
String getName():获取线程名字
void setName(String name):设置线程名字
(记住)static Thread currentThread():获取正在执行的线程对象。
(记住)static void sleep(long millis):线程休眠,参数是要休眠的毫秒值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.YHL

谢谢您的肯定

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值