zoukankan      html  css  js  c++  java
  • Java学习笔记 第九章 多线程和反射

    JAVA学习笔记第九章

    9.多线程和反射

    image-20210609173953352

    image-20210609174359909

    image-20210609174444082

    image-20210609174529498

    9.1线程

    9.1.1创建线程

    image-20210609174911232

    【2】创建线程:线程类——>线程对象

    方式一:继承Thread类

    image-20210609175500155

    image-20210609175905423

    原理图:

    image-20210609180022458

    运行结果:

    image-20210609180050064

    设置线程的名字:

    image-20210609215752339

    image-20210609220004419

    方式一:通过setName设置

    image-20210609215914786

    image-20210609215813994

    方式二:通过构造器和super设置,实际上还是调用父类的有参构造器

    image-20210609220114177

    例子:买车票

    public class BuyTicketThread extends Thread {
        public BuyTicketThread(String name){
            super(name);
        }
        //一共10张票
        static int ticketNum = 10; //多个对象共享10张票
    
        //每个窗口都是一个线程对象:每个对象执行的代码放入run方法中
        @Override
        public void run() {
            //每个窗口后有100个人抢票
            for(int i = 1; i < 100; i++){
                //对票数进行判断
                if(ticketNum > 0) {
                    System.out.println(this.getName()+"买到第" + ticketNum-- + "张票");
                }
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            //多个窗口抢票
            BuyTicketThread t1 = new BuyTicketThread("窗口1");
            t1.start();
    
            BuyTicketThread t2 = new BuyTicketThread("窗口2");
            t2.start();
    
            BuyTicketThread t3 = new BuyTicketThread("窗口3");
            t3.start();
        }
    }
    

    结果:

    image-20210609221624087

    【3】实现Runnable接口

    同理,也需要实现run方法

    image-20210609222007018

    image-20210609222030333

    例子:买车票

    image-20210609223427562

    image-20210609223408724

    由于共享一个线程对象,TicketNum也是共享的

    image-20210609223636388

    【4】实现Callable接口

    image-20210609223839512

    image-20210609224043936

    image-20210609224300116

    FutureTask也实现了Runable接口

    9.1.2线程的生命周期

    image-20210609224634036

    9.1.3线程常用方法

    image-20210609224837232

    (6)设置优先级setPriority

    image-20210609224949364

    image-20210609225125320

    (7)join方法

    image-20210609225508753

    image-20210609225346361

    运行结果:先执行主线程打印1-5,接着执行完子线程,再接着打印6-100

    (8)sleep方法:人为的制造阻塞事件

    image-20210609225706993

    案例:

    image-20210609230018945

    (9)setDaemon方法:设置伴随线程

    image-20210609233201508

    image-20210609233050540

    (10)stop:提前结束线程

    image-20210609233319833

    9.1.4线程安全

    【1】出现问题:

    (1)出现2个或者3个第10张票

    image-20210609233556445

    (2)出现-2, -1, 0张票

    image-20210609233736891

    image-20210609233800086

    解决方法:加锁-》加同步-〉加同步监视器

    加同步代码块:

    image-20210609234113190

    多个线程必须用同一把锁才能锁住

    image-20210609234714283

    image-20210609235016089

    image-20210609235033625

    image-20210609235052063

    image-20210609235314728

    image-20210609235411557

    另一种方式:但是buyTicket()锁住的是this

    image-20210609235548910

    创建多个对象的时候this不是同一个,需要加上static关键字修饰,这样锁住的就是同步监视器 类.class

    image-20210609235837936

    image-20210609235757672

    image-20210610000006194

    image-20210610000035563

    【5】Lock锁

    Lock是一个接口,具有多个实现类,多态,扩展性好

    image-20210610000239903

    使用:即使有异常也能关闭锁

    image-20210610000441220

    image-20210610000516836

    image-20210610000642571

    线程同步的优缺点:

    image-20210610000847861

    9.1.5生产者消费者模型

    image-20210610001132931

    image-20210610120920582

    image-20210610120944392

    image-20210610121005500

    image-20210610121018999

    image-20210610121043712

    解决方式一:

    加同步代码块,synchronized

    解决方式二:

    加同步方法,不能直接在生产者和消费者类中加同步方法,生成的两个对象使用的是不同的锁

    可以在商品类中添加同步方法

    image-20210610121826220

    线程通信的原理:

    image-20210610122310314

    image-20210610122521681

    image-20210610122543005

    image-20210610122645525

    image-20210610122836632

    注意:wait()方法和notify()方法都需要在同步方法和同步代码块中(因为在同步的基础上线程通信才是有效的)

    sleep和wait的区别:sleep进入阻塞,没有释放锁。wait进入阻塞同时释放锁。

    image-20210610123338744

    在等待队列中可能存在多个生产者和消费者:

    使用Condition中的await和signal方法

    image-20210610124828006

    image-20210610125544436

    image-20210610125532189

    生产者:

    image-20210610124948024

    image-20210610125104526

    image-20210610125138813

    消费者:

    image-20210610125404060

    image-20210610125455119

    9.2反射

    image-20210610125748488

    image-20210610150141474

    image-20210610145747792

    9.2.1引入

    美团外卖的接口:Mtwm.java

    //接口定制方:美团外卖
    public interface Mtwm {
        //在线支付功能
        void payOnline();
    }
    

    微信、支付宝、银行卡类:

    public class Wechat implements Mtwm{
        @Override
        public void payOnline() {
            //实现微信支付的功能
            System.out.println("我点外卖使用微信支付");
        }
    }
    
    
    public class AliPay implements Mtwm{
        @Override
        public void payOnline() {
            //实现支付宝支付
            System.out.println("我点外卖用支付宝支付");
        }
    }
    
    public class BankCard implements Mtwm{
        @Override
        public void payOnline() {
            //银行卡支付
            System.out.println("我点外卖用银行卡支付");
        }
    }
    

    测试类

    public class Test {
        public static void main(String[] args) {
            //定义一个字符串,模拟前台的支付方式:
            String str = "支付宝";
            //String str = "微信";
            if ("微信".equals(str)) {  //避免空指针异常str有可能为空
                //微信支付
                //new Wechat().payOnline();
                pay(new Wechat());
            }
            if ("支付宝".equals(str)){
                //支付宝支付
                //new AliPay().payOnline();
                pay(new AliPay());
            }
            if ("银行卡".equals(str)){
                //银行卡支付
                pay(new BankCard());
            }
        }
    
        public static void pay(Wechat wc){
            wc.payOnline();
        }
    
        public static void pay(AliPay ap){
            ap.payOnline();
        }
    
        public static void pay(BankCard bc){
            bc.payOnline();
        }
    }
    
    

    为了提高代码的扩展性

    image-20210610132255016

    但是多态的扩展性还不是最好的,更好的解决方法是反射

    public class Demo {
        public static void main(String[] args) throws Exception{
            //定义一个字符串,模拟前台的支付方式:
            String str = "test01.BankCard";  //实际上是微信类的全限定路径
    
            Class cls = Class.forName(str);
            Object o = cls.newInstance();
            Method method = cls.getMethod("payOnline");
            method.invoke(o);
    
        }
    }
    

    9.2.2Class类

    image-20210610151507061

    image-20210610151710633

    image-20210610151821272

    image-20210610152011991

    image-20210610152052426

    image-20210610152113213

    image-20210610155443337

    image-20210610155650187

    Class c3 = Class.forName("test01.Person");
    

    image-20210610155843191

    ClassLoader loader = Test.class.getClassLoader();
    Class c4 = loader.loadClass("test01.Person");
    

    9.2.3Class类的实例的种类

    image-20210610160629398

    image-20210610161111620

    9.2.4获取构造器和创建对象

    image-20210610162135675

    image-20210610162222470

    指定构造器:

    不填写参数,默认得到空的构造器

    image-20210610162317881

    image-20210610162504097

    image-20210610162607005

    image-20210610162640395

    9.2.5获取属性

    image-20210610162926699

    image-20210610164849338

    image-20210610164930943

    image-20210610165134204

    修饰符是一个具体的数字,如果需要转成字符串:

    image-20210610165240642

    查看属性的修饰符也可以合成一句话:

    image-20210610165318158

    给这个对象的score属性设置值为98

    image-20210610165506479

    给属性赋值,必须要有对象

    9.2.6获取方法

    getMethods:获取运行时的方法和所有父类的方法(被public修饰)

    image-20210610165728565

    image-20210610165908091

    image-20210610165945149

    image-20210610170101055

    image-20210610170115622

    image-20210610170244244

    image-20210610170344096

    image-20210610170429966

    9.2.7获取类的接口、包、注解

    image-20210610170701291

    image-20210610170725058

    获取包名:

    image-20210610170823370

    获取注解:

    image-20210610170852645

    9.2.8反射面试题

    程序的扩展性,需要在程序运行时才确定

    image-20210610171242151

  • 相关阅读:
    POJ2888 Magic Bracelet [矩阵快速幂+Burnside+欧拉函数]
    数列的 GCD [计数问题]
    com组件的注册
    WCF 传输和接受大数据
    数据库中已存在名为 'View_Business' 的对象。
    windows 两个用户,默认其中一个用户登录
    用C#读取,写入ini文件
    小心得,关于串口
    未能加载文件或程序集"Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad
    无法激活服务,因为它不支持 ASP.NET 兼容性
  • 原文地址:https://www.cnblogs.com/wrrr/p/14871888.html
Copyright © 2011-2022 走看看