首页 > 编程语言 >B站宋红康JAVA基础视频教程个人笔记chapter08-09(异常处理+多线程)

B站宋红康JAVA基础视频教程个人笔记chapter08-09(异常处理+多线程)

时间:2024-08-26 10:50:36浏览次数:10  
标签:JAVA Thread void 09 start 线程 new 多线程 public

文章目录

1.异常处理方式1:try-catch-finally

1.1基本结构

try{
}
catch(异常类型1 e){
}
catch(异常类型2 e){
}
finally{ // 无论异常是否发生都执行
}

1.2使用细节

1.将可能出现异常的代码声明再try语句中,一旦代码出现异常,就会自动生成一个对应异常类的对象。并将此对象抛出。
2.针对try中抛出异常类的对象,使用之后的catch语句进行匹配,一旦匹配上,就进入catch语句,一旦处理结束,代码继续向下执行
3.如果不同的异常类型存在子父类的关系,那么父类必须在下面
4.catch中异常处理的方式

4.1.自己编写输出语句 4.2.printStackTrace()打印异常的详细信息e.printStackTrace() 4.3.e.getMessage()

1.3使用细节

1.编译时异常必须处理,否则编译不会通过
2.运行时异常一般需要修改代码,一般是自己编写代码的逻辑错误

1.4 啥样的代码一定要声明在finally中呢?

开发中,有一些资源比如IO流,数据库连接,Socket连接资源,使用完以后,必须显示的声明关闭操作,否则,GC不会自动回收这些资源。进而导致内存泄漏

2.异常处理方式1:throws

1.格式:

public void test() throws 异常类型1,异常类型2{
}

2.其他

子类的异常类型范围不能够大于父类
throw和throws的区别:前者用于产生异常,后者用于处理异常(排出,治理)

3.程序,进程,线程的区别

1.**程序**:为完成特定任务,用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象
2.**进程**:程序的一次执行过程,就是正在内存中运行的应用采用程序(操作系统调度和分配资源的最小单位)
3.**线程** :进程可以进一步细化为线程,是程序内部的一条执行路径,一个进程中至少有一个线程(CPU调度和执行的最小单位)

4.线程的创建

4.1线程的创建方式1:
public class EvenNumberTest {
    public static void main(String[] args) {
        // 3.创建当前Thread子类的对象
        PrintNumber pn = new PrintNumber();

        // 4.通过对象调用start,启动线程,调用当前线程的run方法
        pn.start(); // 已经start的线程不能继续调用start,否则会出现线程状态异常

        //main()方法线程执行的操作
        for(int i=1;i<=10000;i++){
            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+ ":" + i+"**********");
            }
        }

    }
}

// 1.创建一个类继承于Thread
class PrintNumber extends Thread{
    // 2.重写Thread中的run方法---》将此线程要执行的操作声明在此方法体中
    @Override
    public void run(){
        for(int i=1;i<=10000;i++){
            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+ ":" + i);
            }
        }
    }
}
4.2线程的创建方式2:
// 线程创建方式二:实现Runnable接口
public class RunnableTest {
    public static void main(String[] args) {
        // 3.创建实例对象
        EvenNumberPrint e1 = new EvenNumberPrint();

        // 4.此对象传递到Thread的构造器中
        Thread t1 = new Thread(e1);
        // 5.Thread类的实例调用start() 1.启动线程 2.调用线程的run方法
        t1.start();

        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

// 1.实现Runnable接口
class EvenNumberPrint implements Runnable {

    // 2.重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

5.线程类的常用方法和生命周期

1.start():启动线程,调用线程的run()方法
2.run():将线程要执行的操作,声明再run()方法
3.currentThread():获取当前执行代码的线程
4.getName():获取线程名
5.设置线程名:setName()
6.sleep(long millis):静态方法,调用时,可以使得当前线程睡眠指定毫秒数
7.yield():静态方法,一旦执行此方法,就释放CPU 的执行权
8.join():在线程a中通过调用线程b的join()方法,意味着线程a进入阻塞状态,直到线程b执行结束,线程a才结束阻塞状态,继续执行
9.isAlive():判断当前线程是否存活

5.1 线程的生命周期jdk5之前

在这里插入图片描述

6.线程的安全问题和同步机制

1.java是如何解决线程安全问题的?使用线程的同步机制

方式1:同步代码块
synchronized(同步监视器){
// 需要被同步的代码
}
说明:
需要被同步的代码,就是哪些操作共享数据的代码
需要被同步的代码被sync包裹后,其他线程必须等待
同步监视器,俗称锁。那个线程获得了锁,哪个线程就执行需要被同步的代码

2.模拟三个窗口卖票的代码实现(同步代码块)

class SaleTicket implements Runnable {
    int ticket = 100;
    @Override
    public void run() {

        while(true) {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized (this) { // 这里的对象必须是同一个
                if(ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);
                    ticket--;
                } else{
                    break;
                }
            }

        }
    }
}

public class WindowTest {
    public static void main(String[] args) {

        SaleTicket s = new SaleTicket();

        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

2.模拟三个窗口卖票的代码实现(同步方法)

class SaleTicket implements Runnable {
    int ticket = 100;
    boolean flag = true;

    @Override
    public void run() {

        while (flag) {
            show();
        }
    }

    public synchronized void show() { // 这里需要是同一个对象,默认是this
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        // 这里的对象必须是同一个
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);
            ticket--;
        } else {
            flag = false;
        }
    }
}

public class WindowTest {
    public static void main(String[] args) {

        SaleTicket s = new SaleTicket();

        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

3.lock锁的使用
在这里插入图片描述

6.线程之间的通信

6.1为什么需要线程之间的通信

多个线程要完成同一个任务,但是又前后顺序,因此需要协调他们的工作

6.2两个线程交替打印1-100案例
class PrintNumber1 implements Runnable {

    private int num = 1;

    @Override
    public void run() {

        while (true) {
            synchronized (this) {
                notify(); // 一旦执行此方法,就会唤醒wait()中线程优先级最高的一个线程,被唤醒的线程从当初的wait线程开始执行
                if (num <= 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + ": " + num);
                    num++;

                    try {
                        wait(); // 线程一旦执行此方法,就进入等待状态。会释放对同步监视器的调用
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    break;
                }

            }
        }
    }
}

public class PrintNumberTest {
    public static void main(String[] args) {
        PrintNumber1 printNumber1 = new PrintNumber1();
        Thread thread1 = new Thread(printNumber1, "线程1");
        Thread thread2 = new Thread(printNumber1, "线程2");
        thread1.start();
        thread2.start();
    }
}

6.3线程池

如果并发的线程数量很多,并且每个线程都是执行一个很短的时间就结束了。这样频繁的创建线程就会大大的降低系统的效率,因为频繁的创建线程和销毁线程需要时间。因此可以创建多个线程,放到线程池中,使用完放回,可以避免频繁的创建和销毁

标签:JAVA,Thread,void,09,start,线程,new,多线程,public
From: https://blog.csdn.net/qq_61033357/article/details/141432601

相关文章

  • java中哪些集合类是安全的,哪些是不安全的?
    在Java中,有一些集合类是线程安全的,主要包括以下几种:Vector:Vector是ArrayList的线程安全版本,它使用同步方法来确保线程安全。当对Vector进行操作时,需要使用synchronized关键字来同步访问。Hashtable:Hashtable是HashMap的线程安全版本,它使用同步方法来确保线程安......
  • 【精选】数码论坛系统设计与实现(计算机毕业设计福利,计算机毕业设计参考,JAVA毕业设计)
    博主介绍:  ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生......
  • 第四章:行为型模式(11种)《Java设计模式宝典:从入门到精通》
      在进入第四章之前,我为大家准备了设计模式专栏的快速访问链接,方便大家随时查阅:《Java设计模式宝典:从入门到精通》专栏目录地址,点击我即可快速访问到所有设计模式的章节,不漏掉一处学习的知识 [点赞]等会儿兄弟们,这篇文章的干货真的是满满的!......
  • 多线程的使用-->1
    目录1.程序进程线程的定义2.创建线程run方法3.启动线程4.线程优先级5.精灵线程(守护线程)1.程序进程线程的定义程序:一组静态的代码进程:一个处于运行状态的程序。进程=执行内存+线程每当启动一个进程时,至少会有一个线程,称为:主线程线程:程序运行的过程......
  • Java | Leetcode Java题解之第374题猜数字大小
    题目:题解:publicclassSolutionextendsGuessGame{publicintguessNumber(intn){intleft=1,right=n;while(left<right){//循环直至区间左右端点相同intmid=left+(right-left)/2;//防止计算时溢出......
  • 基于javaweb+jsp的鲜花商城系统
    基于javaweb+jsp的鲜花商城系统的设计与实现~开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+JSP工具:IDEA/Ecilpse、Navicat、Maven系统展示前台后台摘要  当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈......
  • Java核心API——io类
     程序的输入与输出我们先来认识一下什么时在程序中输入与输出输入是从外界到程序中的方向,是我们程序用于获取外界信息的过程,是"读"的过程 输出是从程序到外界的方法,是我们程序向外界发送信息的过程,是"写"的过程java.io.InputStream与OutputStream输入流与输出流这......
  • java毕业设计-基于springboot+vue的在线付费自习室管理系统,基于SpringBoot+Vue的自习
    文章目录前言系统功能演示视频项目架构和内容获取(文末获取)具体实现截图用户前台管理后台架构设计MVC的设计模式基于B/S的架构技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站项目开发案例项目相关文件前言博主介绍:✌️码农一枚......
  • Javascript之函数式编程
    一、是什么函数式编程是一种"编程范式"(programmingparadigm),一种编写程序的方法论主要的编程范式有三种:命令式编程,声明式编程和函数式编程相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算......
  • JavaScript中的内存泄露
    一、是什么内存泄漏(Memoryleak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费程序的运行需要内存。只要程序提......