开闭原则
线程的状态有几种?
6中
Thread类枚举类State
NEW 新建状态
RUNNABLE 运行状态
BLOCKED阻塞状态通过sleep(),wait()
WAITTING等待 死等状态
TIMED_WAITTING超时等待状态有一个时间毫秒值
TERMINATED 线程死亡状态
静态代理:就是代理类和真实角色都需要实现同一个接口
代理类:帮助真实角色完成业务功能的增强
真实角色:专注于自己的事情
同步机制:悲观锁(synchronized)
使用同步代码解决线程安全问题: 加了同步锁,其他线程不能更改它数据(针对频繁写入操作)
synchronized(锁对象){
多条语句对共享数据操作;
}
同步方法
public synchronized 返回值类型 方法名(形参列表){ //锁对象:this
...
}
Mybatis框架---->Mybatis-Plus (插件可以使用乐观锁)
什么是Java中的等待唤醒机制?
等待唤醒机制---称为"等待通知",习惯于叫等待唤醒
当前多个线程出现循环等待-----死锁
使用notify() notifyAll() 将阻塞状态中线程进行唤醒,来操作业务数据!
多个线程必须使用的是同一个资源对象!
创建多线程的方式有几种
三种
1)继承关系:
自定一个类继承自Thread类
重写Thread类的run方法
在main中创建当前类对象,启动线程调用start()
2)实现Runnable接口
自定义一个类 实现Runnable接口
重写Runnable接口的run方法
在main中将自定义的类作为资源共享类---创建当前类对象
创建线程类Thread类对象,将资源共享类作为参数传递
分别启动线程调用start()
3)线程池
2.获取一个类的字节码文件有几种方式?
三种
1)Object类的getClass()方法
2)任意Java类型的class属性
3)反射:Class.forName("包名.类名") ;
3.wait方法和sleep方法的区别(经常会的)
1)是否释放锁
当锁对象调用wait方法,立即释放锁;
而sleep(xx):被调用的时候,线程一直处于阻塞状态,不会释放锁
2)来源不同
wait()来源于Object类----- >跟锁对象关系!
为什么将wait():线程等待 ;notify() notifyAll() 线程唤醒,定义Object类中?
因为这些方法和锁有关系,而锁对象可以是任意Java对象!
sleep():来源于Thread类---->只是属于一种状态,跟锁无关
3)他们都会抛出interruptedException:当前状态被中断,都会抛出异常!
多线程实现方式1: 继承关系
SellTicket st1 = new SellTicket() ;
SellTicket st2 = new SellTicket() ;
SellTicket st3 = new SellTicket() ;
//设置线程名称
st1.setName("窗口1") ;
st2.setName("窗口2") ;
st3.setName("窗口3") ;
//启动线程
st1.start() ;
st2.start() ;
st3.start();
三个栈指向三个堆:分别在出售100张票 "没有数据共享"
继承关系具有局限性--->重写run方法----->Thread类的run---->通过实现Runnable接口的run 方法
不仅仅继承run方法,还将其他无关方法继承过来,不利于功能的扩展! (体现不出来:面向接口编程)
多线程实现方式2: (推荐)
"资源共享"
每一个线程都在使用同一个对象 st(SellTicket对象的引用) 体现出 "面向接口编程"
静态代理 模式
最大特点:真实角色和代理类都必须实现同一个接口!
代理类 对真实角色的功能进行方法增强!
代理类
真实角色
SellTicket 实现Runnable接口 完成run方法重写
Thread类 本身实现Runnable接口 完成run方法重写
SellTicket st = new SellTicket() ;
//创建多个线程类对象,将资源共享类作为参数传递
Thread t1 = new Thread(st,"窗口1") ;
Thread t2 = new Thread(st,"窗口2") ;
Thread t3 = new Thread(st,"窗口3") ;
//启动线程
t1.start();
t2.start();
t3.start();
创建型设计模式:对象的创建
* Java提供:简单工厂模式 ---静态工厂方法模式
* 优点:不需要具体类创建具体实例,通过工厂类创建
*
* 弊端:一旦有一个新的类型增,修改工厂类!
*
* 需要提供一个工厂类,负责具体的实例的创建
动物工厂类
public class AnimalFactory {
//构造方法私有化
private AnimalFactory(){ //外界不能创建当前类对象
}
//静态方法
//创建猫的实例
/* public static Cat createCat(){
return new Cat() ;
}
//创建狗的实例
public static Dog createDog(){
return new Dog() ;
}
//创建猪的实例
public static Pig createPig(){
return new Pig() ;
}*/
//优化:利用多态:提供功能扩展
public static Animal createAnimal(String type){
if(type.equals("dog")){
return new Dog() ;
}else if(type.equals("cat")){
return new Cat() ;
}else if(type.equals("pig")){
return new Pig() ;
}else{
System.out.println("对不起,工厂类没有提供者动物的实例创建!");
}
return null ;
}
}
Animal animal = AnimalFactory.createAnimal("dog"); //父类引用指向子类对象
animal.eat();
animal.sleep();
animal = AnimalFactory.createAnimal("cat") ;
animal.eat();
animal.sleep();
标准单例模式之饿汉式:Runtime
* 个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接
public class RuntTimeDemo {
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
// Runtime runtime2 = Runtime.getRuntime();
//System.out.println(runtime==runtime2);
int cpuSize = runtime.availableProcessors();
System.out.println(cpuSize);
runtime.exec("notepad") ;
runtime.exec("mspaint") ;
runtime.exec("calc") ;
}
}
public class Student {
//创建该类实例---(类的实例变量)
// public static Student s = new Student() ;
private static Student s = new Student() ;
private Student(){} //外界不能创建对象
//提供对外的公共访问方法:静态的
public static Student getStudent(){
return s ;
}
}
public class Tests {
public static void main(String[] args) {
/*Student s =new Student() ;
Student s2 = new Student() ;
System.out.println(s==s2) ;//false
System.out.println(s.getClass()==s2.getClass());//true*/
//getClass()---->class 包名.类名
// Student.s = null ; //被外界更改掉
Student s1 = Student.getStudent();
Student s2 = Student.getStudent();
System.out.println(s1==s2);
System.out.println("-----------------");
Programmer p1 = Programmer.getPro();
Programmer p2 = Programmer.getPro();
Programmer p3 = Programmer.getPro();
System.out.println(p1==p2);
System.out.println(p1==p3);
}
}
public class Programmer {
private static Programmer pro = null ;
private Programmer(){}
//p1,p2,p3
//对外公共访问方法
/*public static Programmer getPro(){
synchronized (Programmer.class){
if(pro ==null){
pro = new Programmer() ;
}
return pro ;
}
}*/
public synchronized static Programmer getPro(){//静态同步方法:锁对象:当前类名.class属性
if(pro ==null){
pro = new Programmer() ;
}
return pro ;
}
}
龟兔赛跑
public class Race implements Runnable{
//当类一加载的时候,定义静态变量
//胜利者
private static String winner = null ;
//兔子和乌龟都要执行这个run
@Override
public void run() {
//for循环:表示步数1-100步
for(int x = 1 ; x <= 100 ; x ++){
//真实故事中:兔子要睡觉的,模拟兔子睡觉
if(Thread.currentThread().getName().equals("兔子") && (x % 10 ==0 )){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//定义一个定义比赛结束的方法
boolean flag = gameOver(x) ;
if(flag){
break ;
}
System.out.println(Thread.currentThread().getName()+"跑了====>"+x+"步");
}
}
//比赛结束的方法
private boolean gameOver(int step) {//步数 x
//情况1:如果当前winner不等于null,存在胜利者,比赛结束
if(winner!=null){
return true ;
}{
//情况2: 判断如果当前step>=100 比赛也要结束
if(step>=100){
winner = Thread.currentThread().getName() ;
System.out.println("winner is:"+winner);
return true ;
}
}
return false ;
}
//用户线程
public static void main(String[] args) {
//创建一个资源共享类
Race race = new Race() ;
//创建线程类对象
Thread t1 = new Thread(race,"兔子") ;
Thread t2 = new Thread(race,"乌龟") ;
t1.start();
t2.start();
}
}
Java中等待唤醒机制
*
* SetThread:生产者资源类
* GetThrread:消费者资源类
* Student:学生
public class ThreadDemo {
public static void main(String[] args) {
//创建学生对象
Student s = new Student() ;
//生产者资源类/消费者资源类对象
SetThread st = new SetThread(s) ;
GetThread gt = new GetThread(s) ;
//创建线程了对象
Thread t1 = new Thread(st) ;
Thread t2 = new Thread(gt) ;
t1.start();
t2.start();
}
}
public class GetThread implements Runnable {
private Student s ;
public GetThread(Student s ){
this.s = s ;
}
@Override
public void run() {
//模拟消费者不断使用数据
while(true){
s.get();
}
}
}
public class Student {
private String name ;
private int age ;
private boolean flag ;
//定义一个功能:给学生赋值(产生数据)
public synchronized void set(String name,int age){ //同步方法 锁对象:this
//如果生产者有数据,等待消费者使用数据
if(this.flag){
try {
this.wait(); //立即释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name ;
this.age = age ;
//如果存在数据
this.flag = true ;
//唤醒阻塞中的线程:消费者线程
this.notify();
}
//获取学生的方法
public synchronized void get(){
//判断如果当前没有数据了,等待生产者生产数据
if(!this.flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.name+"---"+this.age);
//判断如果当前没有数据类,唤醒生产者线程,产生数据
this.flag = false ;
this.notify();
}
}
public class SetThread implements Runnable {
private Student s ;
public SetThread(Student s){
this.s = s ;
}
int x = 0 ;
@Override
public void run() {
//模拟生产者不断产生数据
while(true){
if(x % 2 ==0){
/*s.name = "高圆圆" ;
s.age = 41 ;*/
s.set("高圆圆",41);
}else{
/* s.name ="赵又廷";
s.age = 45 ;*/
s.set("耿明刚",26);
}
x ++;
}
}
}
线程组 ThreadGroup 线程组表示一个线程的集合
*
* Thread类中方法:
* public final ThreadGroup getThreadGroup():获取当前所有线程的默认线程组
* ThreadGroup
* public final String getName() :获取默认的线程组名称: (默认就是main)
*
*
* 构造方法:
* ThreadGroup(String name):构造一个新的名称的线程组
*
* 所有的线程默认的线程组就是main线程(用户线程)
public class ThreadGroupDemo {
public static void main(String[] args) {
//method() ;
method2() ;
}
//设置线程组名称
private static void method2() {
// ThreadGroup(String name):构造一个新的名称的线程组
ThreadGroup tg = new ThreadGroup("myMain") ;
//创建线程类对象:可以将线程组对象作为参数传递
//public Thread(ThreadGroup group,String name)
Thread t1 = new Thread(tg,"线程1") ;
Thread t2 = new Thread(tg,"线程2") ;
System.out.println(t1.getThreadGroup().getName());
System.out.println(t2.getThreadGroup().getName());
}
private static void method() {
//创建两个线程类对象
MyThread my1 = new MyThread() ;
MyThread my2 = new MyThread() ;
//获取对应的线程组名称
ThreadGroup tg1 = my1.getThreadGroup();
String name = tg1.getName();
ThreadGroup tg2 = my2.getThreadGroup();
String name2 = tg2.getName();
System.out.println(name);
System.out.println(name2);
}
}
MyCallabe:等待需要被线程池提交的异步任务
public class MyCallable implements Callable<Object> {
//call方法:本身要计算的结果
@Override
public Object call() throws Exception {
for(int x = 0 ; x <100 ; x ++ ){
System.out.println(Thread.currentThread().getName()+":"+x);
}
return null;
}
}
线程池的使用:
* 1)接口:ExecutorService :跟踪一个或者多个异步任务
* 2)如何实例化---->Executors.newFixedThreadPool(int) 工厂方法:
*
* Executors:工厂类
* 提供创建线程池对象的方法
* public static ExecutorService newFixedThreadPool(int nThreads)
*
* ExecutorService
* 方法:
* Future<?> submit(Runnable task) :通过线程池提交异步任务
* <T> Future<T> submit(Callable<T> task):提交异步任务
*
* Future:异步任务计算的结果!
*
*
* 第三种方式:线程池实现---->还是自定义一个类 实现Runnable接口
public class ThreadDemo {
public static void main(String[] args) {
/* new Thread(){
@Override
public void run() {
}
}.start();*/
//创建一个线程池:静态工厂模式
ExecutorService pool = Executors.newFixedThreadPool(2);
//提交异步任务
// Future<?> submit(Runnable task) :通过线程池提交异步任务
/* pool.submit(new MyRunnable()) ;
pool.submit(new MyRunnable()) ;*/
//Callable要比Runnable接口更好
//可以跟踪具体的异常错误(如果执行过程中,线程出现异常,可以跟踪异常信息!)
pool.submit(new MyCallable()) ;
pool.submit(new MyCallable()) ;
//使用完毕,关闭线程池--将底层产生的线程归还线程池中
pool.shutdown();
}
}
public class MyRunnable implements Runnable{
@Override
public void run() {
for(int x = 0 ; x < 100 ; x ++){
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
public class MyCallable implements Callable<Object> {
//call方法:本身要计算的结果
@Override
public Object call() throws Exception {
for(int x = 0 ; x <100 ; x ++ ){
System.out.println(Thread.currentThread().getName()+":"+x);
}
return null;
}
}
public class ThreadDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建存有2条线程的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
//Future:接口:异步计算的结果
Future<Integer> f1 = executorService.submit(new MyCallable(100));
Future<Integer> f2 = executorService.submit(new MyCallable(200));
//V get():获取结果值
Integer i1 = f1.get();
Integer i2 = f2.get();
System.out.println(i1);
System.out.println(i2);
}
}
j ava.util.Timer:定时器 :有线程安排执行务执行一次,或者定期重复执行。
* 构造方法:
* public Timer() 无参构造方法
*
* 成员方法
* public void cancel():取消定时器
* public void schedule(TimerTask task,Date time) :在指定日期时间内执行这个任务
* public void schedule(TimerTask task,long delay):在指定的延迟时间后执行task任务(时间:毫秒)
*
* public void schedule(TimerTask task,
* long delay,
* long period) :在指定的delay延迟时间后开始重复时间间隔period来执行task任务
*
* 需求:
* 在某天的18点将 d://demo文件夹 中的所有的带后缀为.java文件删除掉! (Timer+io流+递归:综合使用)
public class TimerDemo {
public static void main(String[] args) {
//创建一个定时器
Timer timer = new Timer() ;
// public void cancel():取消定时器
//参数1:定时任务:抽象类,定义子类继承自TimerTask
// timer.schedule(new MyTask(timer),3000); :3秒后执行一次这个任务
/* public void schedule(TimerTask task,
long delay,
long period) :在指定的delay延迟时间后开始重复时间间隔period来执行task任务*/
timer.schedule(new MyTask(timer),2000,3000);
}
}
//定时任务
class MyTask extends TimerTask{ //TimerTask实现Runnable接口 ---会使用同步机制
private Timer t ;
public MyTask(Timer t){
this.t = t ;
}
@Override
public void run() {
System.out.println("bom...");
//关闭定时器
//t.cancel() ;
}
}
1.多线程创建方式有几种,列举
1)继承自Thread类 重写run方法,然后创建当前类对象 启动线程
2)实现Runnable接口 重写run方法,然后将当前资源类作为参数传递 到Thread类中 然后启动线程
new Thread(new Runnable(){
public void run(){
...
}
}).start ;
3)线程池
工厂类:Executors
public static ExecutorService newFixedThreadPool(int nThreads)
通过它的子实现对象:ThreadPoolExecutor
7个参数:
corePoolSize
maxmiumPoolSize
handler:自动启用拒绝策略
TimeUnit:计时器
ThreadFactory---创建新的线程对象
DefaultThreadFactory
keepAliveTime:保存存活时间
BlockingQueue queue 阻塞队列(Collection)
ExecutorService
Future submit(Callable<E> call) :提交异步任务
2.什么是单例模式,请列举两种情况
创建对象时候,始终保证内存只有一个对象!
单例模式:
饿汉式:不会出现安全的单例模式 :Runtime
当前类一加载的时候,就立即创建一个对象(只有这一个对象)
1)当前类是一个具体类
2)类的成员位置:创建的当前静态实例变量并且私有化
3)无参构造方法私有化
4)提供对外的公共访问方法:静态方法,并且返回值是当前类本身
public class Student{
private static Student s = new Student() ;
private Student(){}
public static Student getStudent(){
return s ;
}
}
懒汉式:可能出现安全问题的单例模式 (实际开发中:懒加载 / 延迟加载!)
1)当前类是一个具体类
2)不会立即创建一个当前类对象:而是声明当类型的成员变量
3)无参构造方法私有化
4)提供对外的静态的公共访问方法:返回值也是当前类本身
先判断当前是否存在类对象,如果为null,新创建一个对象
返回当前类对象;
class Teacher{
private static Teacher t = null ;
private Teacher(){}
//t对象被共用
//并发的线程 访问公共变量:就会出现冲突
//使用同步机制:synchronized
public synchronized static Teacher getTeacher(){
if(t==null){ //需要使用的时候,才创建对象!
t = new Teacher() ; //新建一个对象
}
return t ;
}
}
Teacher t1 = Teacher.getTeacher() ;
Teacher t2 = Teacher.getTeacher() ;
3.什么是简单工厂以及工厂方法模式
简单工厂:静态工厂方法模式
优点:不需要具体类 new 具体类,而是需要通过工厂类
工厂类的职责:就是负责具体类的对象的创建!
弊端:
当有新的类型增加,需要频繁的修改工厂类代码! (可以使用多态!)
工厂方法:
需要有工厂接口,工厂接口中的方法 返回值某个抽象类型
抽象类还需要有具体的子类,而具体类对象的创建工作:由工厂接口的 的子实现类(具体类的工厂类)
interface Factory{
public abstract Animal createAnimal() ;
}
//狗的工厂类
class DogFactory implements Factory(){
public Animal createAnimal(){
return new Dog() ;
}
}
优点:面向接口编程而且使用接口多态,提供功能扩展性
弊端:代码量大:一个新的类型增加,需要提供工厂类
4.集合和数组的区别
长度区别
集合:可变
数组:固定
存储元素
集合:可以存储任意类型的元素 :引用类型
数组:既可以存储引用类型,也可以存储基本类型 (元素类型必须统一)
存储的数据类型区别
数组:数据类型:必须统一
集合:只能引用类型
5.多线程的同步机制是什么
解决:
并发线程中针对公共变量访问冲突变量
同步机制:四种
1)ThreadLocal -----> 数据库连接池会使用! (创建Connection:连接对象)
2)同步代码块/同步方法 synchronized
3)wait()或者 notify()
4)volatile
MES系统
URL是URI的子集
URI
/dianshang/login
URI指定的具体的访问的路径:
协议
ftp协议
迅雷协议
邮件协议
jdbc:
http协议
URL:
网络协议: http/ https:加密协议 更安全
http://www.baidu.com:80/index.html
http://localhost:8080/dianshang/login
本文深入探讨了面向对象设计的六大原则:单一职责原则、开闭原则、里氏替换原则、依赖注入原则、接口分离原则和迪米特原则。同时,介绍了设计模式的概念,如创建型模式、结构型模式和行为型模式,以及常见的设计模式如工厂模式、单例模式等。强调了设计模式在软件开发中的重要性,以提高代码的可复用性和可维护性。此外,还讨论了线程安全、多线程实现方式、线程池和Java中的等待唤醒机制等并发编程相关知识点。
848

被折叠的 条评论
为什么被折叠?



