匿名内部类和多线程

  • 1. 匿名内部类
  • 1.1 接口你还记得吗???
  • 1.2 类的本体
  • 2. 多线程
  • 2.1 什么是进程
  • 2.2 什么是线程
  • 2.3 线程和进程的关系
  • 2.4 线程优缺点
  • 2.5 Java中创建线程的两种方式【low】
  • 2.6 Thread中常用方法
  • 2.7 线程锁操作问题
  • 2.7.1 生活场景分析
  • 2.7.2 代码实现分析
  • 2.7.3 售票抢占问题
  • 2.7.4 同步代码块
  • 2.8 守护线程/后台线程



匿名内部类和多线程)

1. 匿名内部类

1.1 接口你还记得吗???

interface A {
    	成员变量 缺省属性 public static final 定义时必须初始化
    	成员方法 缺省属性 public abstract 该方法没有方法体
    	默认方法 default修饰,当前方法可以拥有方法体 JDK 1.8 新特征
    }
    
    一个类遵从接口
    class TypeA implements A {
    	要求实现接口中所有缺省属性为pubilc abstract成员方法
    }
    
    当前类创建对象之后,我们就可以调用当前TypeA类实现接口A 要求完成的方法。

1.2 类的本体

class TypeA implements A {
    	@Override
    	public void testA() {
    		System.out.println("一个类遵从接口A 实现的方法");
    	}
    }
    
    class TypeB implements A {
    	@Override
    	public void testA() {
    		// TODO Auto-generated method stub
    		
    	}
    }
    
    class Person {
        属性
        方法
        构造方法
    }
    	这里可以将大括号以内的内容看做是【类的本体】
    	TypeA和TypeB这两个类,他们【类的本体】,是因为遵从同一个接口A。这里必须完成对应的方法,该方法就是【类的本体】。而且TypeA和TypeB这两个类最终的目标,就是通过该类对象使用【类本体】中实现的方法。
       开发中我们发现,类的名字貌似太多的约束,并且非常不重要。这里可以采用【匿名内部类方式 Anonymous Inner Type】。
       【最终目的】是为了实现类的本体

    package com.qfedu.a_anonymous;
    
    interface SingleDog {
    	void test();
    }
    
    class SingleDogOne implements SingleDog {
    	@Override
    	public void test() {
    		System.out.println("非诚勿扰,相亲大会,爱情保卫战");
    	}
    }
    
    public class Demo2 {
    	public static void main(String[] args) {
    		new SingleDogOne().test();
    		
    		/*
    		 * 这里是SingleDog接口的引用数据类型变量,指向一个SingleDog接口对应匿名内部类对象
    		 * 大括号里面的内容是因为【遵从】接口SingleDog需要完成的方法,也就是【类的本体】。同时
    		 * 这里隐含一个【遵从关系】。
    		 * 
    		 * 当前类的本体没有对应的名字,这就是匿名类!!!
    		 * 实际上是SingleDog匿名内部类对象赋值给SingleDog接口引用数据类型变量。【多态】
    		 */
    		SingleDog sd = new SingleDog() {
    			@Override
    			public void test() {
    				System.out.println("SingleDog接口匿名内部类对象,赋值给接口引用数据类型变量");
    			}
    		};
    		
    		sd.test();
    		
    		// SingleDog接口匿名内部类的匿名对象,直接调用实现的方法
    		new SingleDog() {
    			
    			@Override
    			public void test() {
    				System.out.println("SingleDog接口匿名内部类的匿名对象,直接调用实现的方法");
    			}
    		}.test();
    		
    		// SingleDog接口匿名内部类的匿名对象 直接作为方法参数
    		testAIT(new SingleDog() {
    			
    			@Override
    			public void test() {
    				System.out.println("SingleDog接口匿名内部类的匿名对象 直接作为方法参数");
    			}
    		});
    		
    		// Lambda表达式!!!
    		testAIT(() -> System.out.println("Lambda表达式")); 
    	}
    	
    	public static void testAIT(SingleDog sd) {
    		sd.test();
    	}
    }

2. 多线程

2.1 什么是进程

进程对于计算机而言就是一个独立的程序!!!
例如:
	LOL PUBG WOT CSGO GTA5 QQ 微信

这些程序是向系统申请资源
	CPU 内存 硬盘 网络 GPU
	1. 独立性
	2. 互斥性
	3. 数据独立性

2.2 什么是线程

线程是进程的一部分,通常情况一个进程(程序)都是有多个线程组成的!!!
例如:
	QQ
		私聊 群聊
	LOL 
		游戏 QT 打字
	电脑管家
		电脑体检 垃圾清理 病毒查杀 电脑加速
		
线程使用的是程序内部资源
	每一个线程,都要想程序(进程)申请资源,并且当前很多资源都是【共享资源】
	线程在运行过程中存在很大程度
		【抢占式运行】
	
	目前的操作系统都是"多任务"系统。依赖于在单位时间以内,给不同的程序分出不同的时间片,执行程序,用户的体验就是同时在执行多个程序。
	线程会抢占进程内的时间片.
	
线程存在的特征:
	1. 抢占
	2. 共享资源
	3. 容易导致死锁

2.3 线程和进程的关系

一个进程最少有一个线程!!!
	如果一个进程所有的线程都关闭,那么该进程也会随之关闭!!!

线程是用的是进程中资源。
线程在进程中运行时,是【抢占式】执行!!!

Java中一个Hello World程序,最少有几个线程???
	2 √ 
		1. 主线程
		2. JVM的GC线程 GC垃圾清理!!!

2.4 线程优缺点

优点:
	1. 可以提升用户体验,可以同时执行多个功能
	2. 可以提高资源的利用率
	
缺点:
	1. 线程过多的情况下,会导致计算机卡顿
	2. 占用过多资源
	3. 存在共享资源问题
	4. 极易导致死锁

2.5 Java中创建线程的两种方式【low】

1. 继承Thread类
    2. 实现Runnable接口

    package com.qfedu.b_thread;
    
    /**
     * 自定义线程类,继承Thread类
     * Thread类是Java中所有线程的基类
     * 
     * @author Anonymous
     *
     */
    class MyThread1 extends Thread {
    	/*
    	 * run方法是线程执行方法。
    	 * 一个线程启动,run方法中的内容就是线程功能代码
    	 * 
    	 * What will be run 跑啥
    	 */ 
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("自定义线程继承Thread类");
    		}
    		
    	}
    }
    
    /**
     * 自定义线程类遵从Runnable接口,实现【函数式接口】Runnable接口
     * 唯一方法 run方法
     * @author Anonymous
     *
     */
    class MyThread2 implements Runnable {
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("自定义线程类遵从Runnable接口");
    		}
    	}
    	
    }
    public class Demo1 {
    	public static void main(String[] args) {
    		// 继承Thread类自定义线程启动方法
    		// 1. 创建自定义线程类对象
    		MyThread1 mt1 = new MyThread1();
    		
    		// 2. 指定start方法,start方法来源于Thread类
    		mt1.start();
    		
    		// 遵从Runnable接口自定义线程启动方法
    		// 1. 调用Thread类构造方法 使用Runnable接口的线程类作为构造方法参数
    		Thread mt2 = new Thread(new MyThread2());
    		
    		// 2. 利用Thread类对象启动线程,调用start方法
    		mt2.start();
    		
    		for (int i = 0; i < 100; i++) {
    			System.out.println("主线程");
    		}
    	}
    }
以上两种方式,虽然不是最终的线程处理方式,但是我们需要了解一个内容
	1. Java中的继承是单继承还是多继承?
		单继承,Java中的所有类有且只能有一个【直接父类】
	2. Java中一个类遵从接口有限制吗?
		Java中的类可以同时遵从多个接口

如果按照继承Thread类方式来完成自定义线程,那么当前自定义线程类是否还可以继承其他类?
	不能,这里语法存在限制,并且会影响到代码中的逻辑

一个类遵从接口,无非就是增加了一个功能!!!并且不会影响到基本的继承流程!!!

【墙裂推荐】
	自定义线程类遵从Runnable接口实现。

【重点】
调用run方法和start方法有区别吗???
	如果一个线程类对象,调用run方法,那就是一个普通方法。不存在线程运行。
	线程对象有且只有调用start方法启动线程,才算是线程运行!!!

2.6 Thread中常用方法

Constructor
    	Thread();
    		创建一个线程对象,没有明确的执行目标,并且线程的名字为默认名字
            
    	Thread(Runnable target);
    		使用Runnable接口的实现类作为当前Thread线程类构造方法参数,Runnable接
    		口实现类明确当前线程执行的内容是什么。线程名字为默认名字
    		target What will be run? 跑啥
    		
    	Thread(Runnable target, String name);
    		使用Runnable接口的实现类作为当前Thread线程类构造方法参数,Runnable接
    		口实现类明确当前线程执行的内容是什么。线程名字为参数指定名字
    		target What will be run? 跑啥
    
    Method:
    	String getName();
    		获取当前线程对象的名字
    	void setName(String name);
    		设置当前线程对象的名字
    	int getPriority()
    		获取当前线程对象的优先级,优先级数据范围 【1 ~ 10】 默认为5
    		1最低 10最高
    	void setPriority(int priority);
    		设置当前线程的优先级
    		
    	static void sleep(int ms);
    		在哪一个线程代码中执行,哪一个线程休眠指定的毫秒数
    		
    	static Thread currentThread();
    		在哪一个线程代码中执行,获取当前线程对象

2.7 线程锁操作问题

2.7.1 生活场景分析
电影院
	<<八佰>>
	100张票
	美团 猫眼 淘票票

100张票对于三个销售渠道而言,是一个共享资源。并且要求不得重复!!!
2.7.2 代码实现分析
美团,猫眼,淘票票这里可以认为是三个售票线程。

100张票是一个共享资源。而且是三个线程对象共享内容
100张票如何保存,用什么变量保存?
	局部变量
		在方法内定义,从定义位置开始,到当前方法运行结束销毁。不能再次使用。
		局部变量不具有共享数据特征,同时也不具备数据持久化特征
		
		
	成员变量
		成员变量是随着类对象的创建而存在,并且是属于当前类对象的,不同的类对象的
		数据没有任何的共享特征,类对象销毁当前成员变量销毁,所以具有一定的持久
		性。
		
	静态成员变量
		在目前情况下,静态成员变量可以提供给三个线程对象使用,同时也是一个可以满
		足程序从开始到最后退出都可以存在的数据。具有共享特征,同时具有持久化特征
2.7.3 售票抢占问题

java 匿名内部类 参数 java匿名内部类实现多线程_System

2.7.4 同步代码块
synchronized (锁·对象) {
    			
    }
    	在synchronized 同步代码块以内的内容有且只能允许一个线程存在。一旦有线程进入同步代码块以内,锁对象起作用,不再允许其他线程进入。
        锁对象要求
            1. 被限制的线程使用的锁对象是同一个对象
            2. 锁对象选择不得影响其他功能线程运行。
            3. 锁对象可以采用类锁 SaleTicket.class
            4. 如果在同步代码块内使用sleep方法,会不会开锁???
2.8 守护线程/后台线程
守护线程/后台线程,大量的充斥在软件中,一般用于在用户不可见情况下偷偷摸摸的做一些事情!!!
	守护线程有一个特征:
		一旦程序中有且只有一个守护线程,当前守护线程会自动销毁。

WeGame	
	LOL大厅等待
	--| 下载更新包 守护线程

守护线程一般用于
	日志记录 数据下载 数据传输 ...