Java 线程和反射---尚硅谷Java视频学习

news2024/11/24 2:33:23
  • 1.Java程序在运行得时候默认就会产生一个进程
  • 2.这个进程会有一个主线程
  • 3.代码都在主线程中执行

线程的生命周期

在这里插入图片描述

线程的执行方式

public class Java02_Thread {
    public static void main(String[] args) throws Exception {
        // TODO 线程 - 执行方式(串行,并发)
        // 串行执行:多个线程连接成串,然后按照顺序执行
        // 并发执行:多个线程是独立,谁抢到了CPU得执行权,谁就能执行

        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
		
        t1.start();
        t2.start();

        // 将线程连接成串
        t1.join();
        t2.join(); //t1-t2

        System.out.println("main线程执行完毕");
    }
}
// TODO 第一个线程
class MyThread1 extends Thread {
    // 重写运行指令

    public void run() {
        System.out.println("MyThread-1 : " + Thread.currentThread().getName());
    }
}
// TODO 第二个线程
class MyThread2 extends Thread {
    // 重写运行指令

    public void run() {
        System.out.println("MyThread-2 : " + Thread.currentThread().getName());
    }
}

自定义线程

public class Java04_Thread_Run {
    public static void main(String[] args) throws Exception {

        // TODO 线程 - 运行

        MyThread3 t3 = new MyThread3();
        t3.start();

        MyThread4 t4 = new MyThread4();
        t4.start();

        MyThread5 t5 = new MyThread5("t5");
        MyThread5 t55 = new MyThread5("t55");

        t5.start();
        t55.start();


        System.out.println("main线程执行");
    }
}

// TODo 自定义线程
// 1. 继承线程类(父类)
// 2. 重写run方法
class MyThread3 extends Thread {
    @Override
    public void run() {
        System.out.println("t3 线程执行");
    }
}

class MyThread4 extends Thread {
    @Override
    public void run() {
        System.out.println("t4 线程执行");
    }
}

class MyThread5 extends Thread {
    private String threadName;

    public MyThread5(String name) {
        threadName = name;
    }

    @Override
    public void run() {
        System.out.println(threadName + " 线程执行");
    }
}

 // TODO 构建线程对象时,可以只把逻辑传递给这个对象
        //      传递逻辑时,需要遵循规则:() -> { 逻辑 }
        Thread t6 = new Thread(() -> {
            System.out.println("线程执行1");
        });

        t6.start();
// TODO 构建线程对象时,可以传递实现了Runnable接口得类得对象,一般使用匿名类
        Thread t8 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行");
            }
        });

        t8.start();

线程池

所谓得线程池,其实就是线程对象得容器
可以根据需要,在启动时,创建一个或者多个线程对象

        // Java种有4种比较常见得线程池
        // 1. 创建固定数量得线程对象
        //    ExecutorService是线程服务对象
        //ExecutorService executorService = Executors.newFixedThreadPool(3);
        // 2. 根据需求动态创建线程
        //ExecutorService executorService = Executors.newCachedThreadPool();
        // 3. 单一线程
        //ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 4. 定时调度线程
        ExecutorService executorService = Executors.newScheduledThreadPool(3);



        for ( int i = 0; i < 5; i++ ) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }

线程同步

public class Java06_Thread_Syn {
    public static void main(String[] args) throws Exception {
        // synchronized - 同步关键字
        // 多个线程访问同步方法时,只能一个一个访问,同步操作
        // synchronized关键字还可以修饰代码块,称之为同步代码块
        /*
           synchronized( 用于同步得对象 ) {
               处理逻辑
           }

         */
        Num num = new Num();

        User user = new User(num);
        user.start();

        Bank bank = new Bank(num);
        bank.start();

    }
}
class Num {

}
class Bank extends Thread {
    private Num num;
    public Bank( Num num ) {
        this.num = num;
    }
    public void run() {
        synchronized (num) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("9:00, 开发,开始叫号");
            num.notifyAll();
        }
    }
}
class User extends Thread {
//    public synchronized void test() {
//
//    }
    private Num num;
    public User( Num num ) {
        this.num = num;
    }
    public void run() {

        synchronized ( num ) {
            System.out.println("我是号码1,银行还没开门,我需要等一会");
            try {
                num.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println("叫到我得号了,该我办业务了。");
        }
    }

wait & sleep

    1. 名字
        wait : 等待
        sleep : 休眠
  • 2.从属关系
        wait : Object, 成员方法
        sleep : Thread, 静态方法
    1. 使用方式
        wait : 只能使用在同步代码中
        sleep : 可以在任意地方法使用
    1. 阻塞时间
       wait : 超时时间(会发生错误)
       sleep : 休眠时间(不会发生错误)
    1. 同步处理
       wait : 如果执行wait方法,那么其他线程有机会执行当前的同步操作。
       sleep : 如果执行sleep方法,那么其他线程没有机会执行当前的同步操作。

线程的安全问题

所谓的线程安全问题,其实就是多个线程在并发执行时,修改了共享内存中共享对象的属性,导致的数据冲突问题

public class Java07_Thread_Safe {
    public static void main(String[] args) throws Exception {
        User7 user = new User7();

        Thread t1 = new Thread(()->{
            user.name = "zhangsan";
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(user.name);
        });
        Thread t2 = new Thread(()->{
            user.name = "lisi";
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(user.name);
        });
        t1.start();
        t2.start();
        System.out.println("main线程执行完毕");
    }
}
class User7 {
    public String name;
}

在这里插入图片描述
栈内存是独享的,堆内存是共享的。两个线程访问同一个对象时,若对对象的属性进行修改,会引起冲突。

反射

  • 常用方法和操作
public class Java01_Reflect {
    public static void main(String[] args) throws Exception {
        // TODO 反射

        // 多态
        User user = new Child();
        user.test1();
        //user.test2();

        // 类对象
        Class<? extends User> aClass = user.getClass();

        // TODO 获取类的名称
        System.out.println(aClass.getName()); // 获取类的完整名称(包含包名)
        System.out.println(aClass.getSimpleName()); // 获取类的名称
        System.out.println(aClass.getPackageName()); // 获取类的包的名称

        // TODO 获取类的父类
        Class<?> superclass = aClass.getSuperclass();
        System.out.println(superclass);

        // TODO 获取类的接口
        Class<?>[] interfaces = aClass.getInterfaces();
        System.out.println(interfaces.length);

        // TODO 获取类的属性
        Field f = aClass.getField("xxxxx"); // public权限的属性
        Field f1 = aClass.getDeclaredField("xxxxx"); // 所有权限

        Field[] fields = aClass.getFields();// 所有public权限的属性
        Field[] declaredFields = aClass.getDeclaredFields(); // 所有权限

        // TODO 获取类的方法
        Method method = aClass.getMethod("test2");// public
        Method xxxx = aClass.getDeclaredMethod("xxxx"); // 所有权限

        Method[] methods = aClass.getMethods();// public
        Method[] declaredMethods = aClass.getDeclaredMethods(); // 所有权限

        // TODO 构造方法
        Constructor<? extends User> constructor = aClass.getConstructor();
        Constructor<?>[] constructors = aClass.getConstructors();
        aClass.getDeclaredConstructor();

        // TODO 获取权限(修饰符) :多个修饰符会融合成一个int值
        int modifiers = aClass.getModifiers();
        boolean aPrivate = Modifier.isPrivate(modifiers);
    }
}
class User {
    public void test1() {
        System.out.println("test1...");
    }
}
class Child extends User {
    public void test2() {
        System.out.println("test2...");
    }
}
  • 类加载器
    Java种的类主要分为3种:
  • Java核心类库种的类:String, Object
  • JVM 软件平台开发商
  • 自己写的类,User, Child
    类加载器也有3种:
    1. BootClassLoader : 启动类加载器(加载类时,采用操作系统平台语言实现)
    1. PlatformClassLoader :平台类加载器
    1. AppClassLoader : 应用类加载器
public class Java02_Reflect_ClassLoader {
    public static void main(String[] args) throws Exception
        // TODo 获取类的信息
        Class<Student> studentClass = Student.class;
        // 获取类的加载器对象
        ClassLoader classLoader = studentClass.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());

        Class<String> stringClass = String.class;
        // 获取类的加载器对象
        ClassLoader classLoader1 = stringClass.getClassLoader();
        System.out.println(classLoader1);

        // 加载Java核心类库 > 平台类库 > 自己类
    }
}
class Student {

}

使用反射实现登录功能

public class Java03_Reflect_Test {
    public static void main(String[] args) throws Exception {

        // TODO 反射 - 练习
        // 员工的登录功能,

        // 构造方法对象
        Class empClass = Emp.class;
        Constructor declaredConstructor = empClass.getDeclaredConstructor();
        // 构建对象
        Object emp = declaredConstructor.newInstance();

        // 获取对象的属性
        Field account = empClass.getField("account");
        Field password = empClass.getField("password");

        // 给属性赋值
        account.set(emp, "admin");
        password.set(emp, "admin");

        // 获取登录方法
        Method login = empClass.getMethod("login");

        // 调用方法
        Object result = login.invoke(emp);

        System.out.println(result);
    }
}
// 员工
class Emp {
    public String account;
    public String password;

    public boolean login() {
        if ( "admin".equals(account) && "admin".equals(password) ) {
            return true;
        } else {
            return false;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/25723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASP.NET Core 3.1系列(14)——分布式缓存Redis的使用

1、前言 前一篇博客介绍了ASP.NET Core中本地缓存MemoryCache的使用方法。相较于本地缓存&#xff0c;分布式缓存更加适合大多数项目应用场景&#xff0c;下面就来介绍一下如何在ASP.NET Core中对Redis缓存进行相关操作。 2、分布式缓存接口——IDistributedCache 对于分布式…

pytorch深度学习实战24

第二十四课 VGG网络 VGG是Oxford的Visual Geometry Group的组提出的&#xff08;大家应该能看出VGG名字的由来了&#xff09;。该网络是在ILSVRC 2014上的相关工作&#xff0c;主要工作是证明了增加网络的深度能够在一定程度上影响网络最终的性能。VGG有两种结构&#xff0c;分…

远程重启电脑

一、设置电脑允许自动启动 在远程计算机上编辑设置远程注册表 步骤1. 按“WindowsR”键调用运行对话框。输入“services.msc”并点击“确定”。 步骤2. 在“服务”窗口中&#xff0c;双击“RemoteRegistry”以检查其状态。 步骤3. 将启动类型更改为“自动”。 二、查找远程计…

SPARKSQL3.0-各阶段自定义扩展规则源码剖析

一、前言 这一节主要介绍如何自定义扩展各阶段规则 虽然spark内部提供了很多优化规则&#xff0c;但在实际工作中&#xff0c;经常因为业务需求需要自定义扩展优化器或解析器&#xff0c;故自己实现一个优化器才对sparksql有更深的理解 二、扩展范围 spark在扩展方便做的很…

vue.js毕业设计,基于vue.js前后端分离教室预约小程序系统设计与实现

功能介绍 【后台管理功能模块】 系统设置&#xff1a;设置关于我们、联系我们、加入我们、法律声明 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0…

从零开始学前端:DOM、BOM、焦点事件 --- 今天你学习了吗?(JS:Day20)

从零开始学前端&#xff1a;程序猿小白也可以完全掌握&#xff01;—今天你学习了吗&#xff1f;&#xff08;JS&#xff09; 复习&#xff1a;从零开始学前端&#xff1a;CSSOM视图模式 — 今天你学习了吗&#xff1f;&#xff08;JS&#xff1a;Day19&#xff09; 文章目录从…

java8 (jdk 1.8) 新特性——Stream ApI

在java8 中&#xff0c;有两个最重要的改变&#xff0c;一个就是之前了解的Lmbda java8 (jdk 1.8) 新特性——Lambda ,还有一个就是Stream Api 1. 什么是Stream API 简单来说就是一个类库&#xff0c;里边有一些方法方便我们对集合数据进行操作&#xff0c;就好像使用 SQL 语…

Windows cmd 命令及Linux 环境下导入导入mysql 数据库

文章目录一、背景二、Windows cmd 导入导出mysql 数据库1.导出数据库三种方式&#xff08;导出数据库时不需要连接数据库&#xff09;2. 操作步骤2.导入数据库三、linux 环境下导入导出数据库一、背景 最近在本机上安装了一个WMware 虚拟机&#xff0c;需要从本机&#xff08;…

从三层架构说起,谈谈对历史项目的小改造

项目背景说明 最近接手一个 “老” 项目的需求修改&#xff0c;项目整体基于 .net core 3.1 平台&#xff0c;以传统的三层架构为基础构建。了解需求后&#xff0c;逐步对原有项目框架进行大概的了解&#xff0c;主要是熟悉一些框架的开发规范&#xff0c;基本工具类库的使用&…

寒亭5.8万亩盐碱稻 国稻种芯·中国水稻节:山东潍坊插秧期

寒亭5.8万亩盐碱稻 国稻种芯中国水稻节&#xff1a;山东潍坊插秧期 新京报讯&#xff08;记者赵利新&#xff09;新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff…

MMRotate 全面升级,新增 BoxType 设计

引言&#xff1a;大大降低水平框检测器改旋转框检测器的难度 MMRotate 是一个基于 PyTorch 和 MMDetection 的开源旋转框目标检测工具箱。它将目标检测从水平框扩展到旋转框&#xff0c;为场景文字、遥感影像、自动驾驶等领域的应用打下了基础&#xff0c;为学术界和产业界提供…

瞄准镜-第12届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第82讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

数据结构——单链表

一.简介 上一篇文章&#xff0c;我们介绍了线性表中的顺序表。 而顺序表拥有一些缺陷 1.空间不够时需要增容&#xff0c;增容需要付出代价 2.为避免重复扩容&#xff0c;我们进行指数扩容&#xff0c;可能会造成空间浪费 3.顺序表从开始位置连续存储&#xff0c;插入删除数…

卡特尔世界杯来了,只喝精酿啤酒不玩望京扑克,其实也是一种缺失

北京时间2022年11月20日&#xff0c;卡特尔世界杯正式拉开了序幕&#xff0c;全球都进入了世界杯时间。世界杯的开幕&#xff0c;最高兴的还是球迷朋友&#xff0c;大家可以欢聚一堂&#xff0c;喝着精酿啤酒看着足球&#xff0c;那滋味别提多舒服了。 世界杯对于广大球迷来说&…

表的增删查改

目录 插入数据 基本查询 更新数据 清空数据 聚合函数 group by子句 内置函数 基本查询练习 多表查询 子查询 合并查询 表的内外连接 插入数据 单行—全列插入 如下图&#xff0c;全列插入可以省略要在哪些列插入&#xff01; 多行—指定列插入 如下图&#xff0…

安装 Red Hat Enterprise Linux 9.1 虚拟机

目录1. 官方下载链接与新闻2. 安装提示3. 系统安装步骤&#xff08;1&#xff09;进入系统引导界面&#xff08;2&#xff09;进入【系统语言选择】界面&#xff08;3&#xff09;进入【安装信息摘要】界面① 设置【root密码】② 设置【安装目的地】&#xff08;4&#xff09;进…

【python】使用python将多个视频合并、延长视频的时间

今天做知识分享的时候&#xff0c;最后保存的视频时长是58分钟&#xff0c;那么如何改变视频的时长&#xff0c;将视频时长改为一个小时呢&#xff1f; 下面提供3个方案&#xff1a; 方案1&#xff0c;重新录&#xff0c;很显然&#xff0c;不合理&#xff1b; 方案2&#xf…

蓝屏page_fault_in_nonpaged_area的解决办法

用户在操作电脑的过程中&#xff0c;难免会遇到蓝屏问题&#xff0c;最近就有用户遇到电脑蓝屏重启无限循环&#xff0c;提示代码page_fault_in_nonpaged_area&#xff0c;这要如何解决呢&#xff1f;下面就来看看详细的解决办法。 page_fault_in_nonpaged_area蓝屏代码解决方法…

【MySQL篇】第一篇——数据库基础

目录 什么是数据库 主流数据库 基本使用 MySQL安装 连接服务器 服务器管理 服务器&#xff0c;数据库&#xff0c;表关系 使用案例 创建数据库 使用数据库 创建数据库表 表中插入数据 查询表中的数据 数据逻辑存储 MySQL架构原理 MySQL整体逻辑架构 MySQL逻辑…

Eureka架构篇 - 服务发现

前言 从客户端与服务端两个角度概述一下Eureka服务发现的原理&#xff0c;如下&#xff1a; 客户端 依赖自动装配机制&#xff0c;客户端启动时就会从Eureka服务端全量获取服务实例的注册信息并缓存到本地。之后每隔30秒向Eureka服务端发起增量获取的请求&#xff0c;如果增…