【java初学】匿名内部类和多线程

匿名内部类和多线程

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 {
    属性
    方法
    构造方法
}
	这里可以将大括号以内的内容看做是【类的本体】
	TypeATypeB这两个类,他们【类的本体】,是因为遵从同一个接口A。这里必须完成对应的方法,该方法就是【类的本体】。而且TypeATypeB这两个类最终的目标,就是通过该类对象使用【类本体】中实现的方法。
   开发中我们发现,类的名字貌似太多的约束,并且非常不重要。这里可以采用【匿名内部类方式 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 售票抢占问题

在这里插入图片描述

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

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

守护线程一般用于
	日志记录 数据下载 数据传输 ...
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值