第二十五天
线程的生命周期
1.线程的创建启动 start
2.线程的等待运行 等cpu分配线程
3.线程的运行 抢占 运行
4.线程的阻塞 wait sleep 锁
5.线程的消亡 destroy
join方法
父线程等待子线程执行完在执行
package com.qf.d_zuoye; class FatherThread implements Runnable { @Override public void run() { Thread thread = new Thread(new sonThread()); thread.start(); try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } class sonThread implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } public class Demo1 { public static void main(String[] args) { Thread thread = new Thread(new FatherThread()); thread.start(); } }
生产者与消费者
方法:
wait(); 等待方法 notify(); 唤醒单个线程 notifyAll(); 唤醒多个线程
package com.qf.c_test; class A { private String name; private double jg; private boolean folg; public A(String name, double jg, boolean folg) { this.name = name; this.jg = jg; this.folg = folg; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getJg() { return jg; } public void setJg(double jg) { this.jg = jg; } public boolean isFolg() { return folg; } public void setFolg(boolean folg) { this.folg = folg; } } class Scz implements Runnable { private A a; public Scz(A a) { this.a = a; } @Override public void run() { int cout = 0; while (true) { synchronized (a) { if (a.isFolg()) { if (cout % 2 == 0) { a.setName("宝马"); a.setJg(100); System.out.println("生产了一辆:" + a.getName() + "价格为:" + a.getJg()); } else { a.setName("奔驰"); a.setJg(200); System.out.println("生产了一辆:" + a.getName() + "价格为:" + a.getJg()); } cout++; a.setFolg(false); a.notify(); } else { try { a.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } class Xfz implements Runnable { private A a; public Xfz(A a) { this.a = a; } @Override public void run() { while (true) { synchronized (a) { if (!a.isFolg()) { System.out.println("购买了一辆:" + a.getName() + "价格为:" + a.getJg()); a.setFolg(true); a.notify(); } else { try { a.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } public class Demo1 { public static void main(String[] args) { A a = new A("劳斯莱斯", 3000, false); Scz scz = new Scz(a); Xfz xfz = new Xfz(a); new Thread(xfz).start(); new Thread(scz).start(); } }
线程池
ThreadPoolExecutor 手动创建线程池的方式
七个参数:
MaximumPoolSize 最大线程数 CorePoolSize 核心线程数 Keep-alive times 存活时间 TimeUnit 存活时间的单位 LinkedBlockingQueue 无界队列 ArrayBlockingQueue 有界队列
反射
获取Class对象的三种方式:
package com.qf.d_zuoye; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo2 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException { Class<Son> sonClass = Son.class; Constructor<Son> constructor = sonClass.getConstructor(null); Son son = constructor.newInstance(); //第一种 类.calss 获取 Class<Son> sonClass1 = Son.class; System.out.println(sonClass1); //第二种 将 Son 类的无参构造方法变成一个对象 Class<?> aClass = Class.forName("com.qf.d_zuoye.Son"); System.out.println(aClass); //第三种 通过对象来创建Class 对象 Class<? extends Son> aClass1 = new Son().getClass(); System.out.println(aClass1); } }
第二十六天
反射
获取Class 对象
三种方式
package com.qf.a_class; public class Demo1 { public static void main(String[] args) throws ClassNotFoundException { //三种方式 Class<Person> personClass = Person.class; Class<?> aClass = Class.forName("com.qf.a_class.Person"); Class<? extends Person> aClass1 = new Person().getClass(); } }
获取Constructor对象
构造方法:
package com.qf.b_class; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo1 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<Person> personClass = Person.class; //获取所有的公开的构造方法 Constructor<?>[] constructors = personClass.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } System.out.println("==============="); //获取公开的单个无参构造方法 Constructor<Person> constructor = personClass.getConstructor(); System.out.println(constructor); //获取公开的单个有参构造方法 Constructor<Person> constructor1 = personClass.getConstructor(String.class); System.out.println(constructor1); System.out.println("============="); //获取所有的构造方法 Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } //获取的单个有参构造方法 Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class, int.class); System.out.println(declaredConstructor); Constructor<Person> declaredConstructor1 = personClass.getDeclaredConstructor(); System.out.println(declaredConstructor1); //获取完构造方法 declaredConstructor.setAccessible(true); Person person = declaredConstructor.newInstance("狗蛋", 18); System.out.println(person.name); System.out.println(person.age); } }
获取Method对象
方法:
package com.qf.b_class; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo2 { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Class<Person> personClass = Person.class; //获取所有的公开的方法 Method[] methods = personClass.getMethods(); for (Method method : methods) { System.out.println(method); } //获取单个的公开的方法 Method paly1 = personClass.getMethod("paly", String.class, int.class); System.out.println(paly1); System.out.println("==================================="); //获取所有的方法 Method[] declaredMethods = personClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } //获取单个方法 Method declaredMethod = personClass.getDeclaredMethod("eat"); System.out.println(declaredMethod); Method sleep = personClass.getDeclaredMethod("sleep", String.class); System.out.println(sleep); Method paly = personClass.getDeclaredMethod("paly", String.class, int.class); System.out.println(paly); //获取完方法 赋值 Person person = personClass.getConstructor().newInstance(); declaredMethod.setAccessible(true); declaredMethod.invoke(person); paly.invoke(person,"狗蛋",15); sleep.setAccessible(true); sleep.invoke(person,"二蛋"); } }
获取Field对象
属性:
package com.qf.b_class; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class Demo3 { public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<Person> personClass = Person.class; //获取所有公开的属性 Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field); } //获取单个公开的属性 Field field = personClass.getField("name"); System.out.println(field); //获取所有的属性 Field[] declaredFields = personClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } //获取单个的属性 Field age = personClass.getDeclaredField("age"); System.out.println(age); Field wihgt = personClass.getDeclaredField("wihgt"); System.out.println(wihgt); Field name = personClass.getDeclaredField("name"); System.out.println(name); //获取完属性 赋值 Person person = personClass.getConstructor().newInstance(); name.set(person,"狗蛋"); System.out.println(name.get(person)); age.set(person,15); System.out.println(age.get(person)); wihgt.setAccessible(true); wihgt.set(person,15.5); System.out.println(wihgt.get(person)); } }
设计模式
单例模式
要求在整个程序运行过程中,同一个类只出现一个对象。目的减少内存的消耗。
如何查看对象同一个对象? 看内存地址。如果内存地址一样就是一个对象
package com.qf.b_single; class SingleDog { private static SingleDog singleDog; private SingleDog() { } public static synchronized SingleDog getInstance() { synchronized (SingleDog.class) { if (singleDog == null) { //线程1进来了还没有new 呢,结果线程2抢到执行权利的 //结果线程2 发现singleDog 是空的 new singleDog = new SingleDog(); } } return singleDog; } } //在两个线程中去创建单例对象的时候 如果发现对象内存不一样,就证明线程不安全 class Mythread1 implements Runnable { @Override public void run() { SingleDog instance = SingleDog.getInstance(); System.out.println(instance);//对象的内存地址 } } class Mythread2 implements Runnable { @Override public void run() { SingleDog instance = SingleDog.getInstance(); System.out.println(instance);//对象的内存地址 } } public class Demo2 { public static void main(String[] args) { new Thread(new Mythread1()).start(); new Thread(new Mythread2()).start(); } }
懒汉式: 线程不安全
饿汉式: 线程安全的
效率高: 饿汉式的效率高,因为没有加锁
性能来说: 饿汉式类一加载就必须加载对象,但是懒汉式的当需要的时候才去new
开发中用懒汉
Lambda表达式
lambda表达式被称为闭包。函数式编程,就是为了简化代码,让代码更加简洁。
Lambda表达式的语法格式
接口 接口对象 = ()->表达式; 无参无返回值的 接口 接口对象 = (parameter)->表达式; 有参无返回值的 接口 接口对象 = ()->{表达式;} 无参有返回值的 接口 接口对象 = (parameter)->{表达式;} 有参有返回值的
无参无返回值的
package com.qf.c_lambda; interface Computer { void coding(); } public class Demo2 { public static void main(String[] args) { //接口 接口对象 = ()->表达式; Computer computer = ()-> System.out.println("荞麦大"); //test(()-> System.out.println("嗷嗷叫的敲代码")); test(computer); test(()-> System.out.println("荞麦大")); test(new Computer() { @Override public void coding() { System.out.println("嘻嘻敲打吗"); } }); } public static void test (Computer computer) { computer.coding(); } }
有参无返回值
package com.qf.c_lambda; interface A { //有参无返回值的方法 void eat (String name, int age); } public class Demo3 { public static void main(String[] args) { test(new A() { @Override public void eat(String name, int age) { System.out.println(name+ "年龄为:" + age + ",在吃牛肉"); } }, "狗蛋", 12); //把 方法中的接口 变成了lambada表达式 //接口 接口对象 = (parameter)->表达式; 有参无返回值的 test((name, age)-> System.out.println(name+ "年龄为:" + age + ",在吃牛肉"), "呵呵", 89); } public static void test (A a, String name, int age) { a.eat(name, age); } }
无参有返回值
package com.qf.c_lambda; interface B { int num(); } public class Demo4 { public static void main(String[] args) { test(new B() { @Override public int num() { return 50; } }); test(()->{return 50;}); } public static void test (B b) { System.out.println(b.num()); } }
有参有返回值
package com.qf.c_lambda; interface C { int add(int a, int b); } public class Demo5 { public static void main(String[] args) { //->前面是 啥? 是方法 带小括号的 方法的名字可以省略 //->后面是 啥? 抽象方法的方法体实现的代码 test((a, b) -> a + b, 4, 5); } public static void test(C c, int a, int b) { int sum = c.add(a, b); System.out.println(sum); } }
#
第二十七天
Stream流
基于Lambda之后,jdk8又引入一个关于集合类库目前的弊端的解决方案。叫stream流
方法的名字 | 方法的作用 | 方法种类 | 是否支持链式操作 |
---|---|---|---|
count | 统计个数 | 终结方法 | 否 |
forEach | 遍历数据的 | 终结方法 | 否 |
filter | 过滤数据 | 可以拼接 | 是 |
limit | 取前几个数据 | 可以拼接 | 是 |
skip | 跳过前几个 | 可以拼接 | 是 |
map | 映射方法 | 可以拼接 | 是 |
concat | 拼接 | 可以拼接 | 是 |
收集流
stream.collect(Collectors.toList())
stream.collect(Collectors.toSet())
toList(); 将流转为List集合
toSet(); 将流转为Set集合
toMap();将流转为Map集合
因为真实的开发的时候,最终的结果还是集合 流只是扮演了中间处理数据的角色
package com.qf.a_stream; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class Demo9 { public static void main(String[] args) { ArrayList<String> strings = new ArrayList<>(); strings.add("刘亦菲"); strings.add("蔡徐坤"); strings.add("成龙"); strings.add("杨坤"); strings.add("陈坤"); strings.add("战三坤"); strings.add("损五坤"); strings.add("爱坤"); strings.add("爱坤"); //collect 收集的方法 //stream.collect(Collectors.toList()) 以什么样的方式收集 List<String> list = strings.stream().filter((s) -> s.endsWith("坤")).skip(2).collect(Collectors.toList()); System.out.println(list); Set<String> set = strings.stream().filter((s) -> s.endsWith("坤")).skip(2).collect(Collectors.toSet()); System.out.println(set); } }
第二十八天
数据库MySQL
命令:
#1.连接数据库服务器的命令 mysql -uroot -p #退出命令 exit; show databases; #展示库 create database 库名;#新建库 drop database 库名; #删除库 use 库名; #选中库 show tables;#查表 create table 表名(字段1 数据量类型 , 字段2 数据类型,...)#建表 drop table 表名;#删表 desc 表名; #查表结构 alter table 表名 drop 字段; #删字段 alter table 表名 add 字段 数据类型;#添加字段 decimal(8,2) 关键字 alter table 表名 add 字段 数据类型 after 字段;#指定添加到哪里 alter table 表名 modify 字段 新数据类型; #修改数据类型 alter table 表名 change 字段 新字段 新数据类型 ;#字段和数据类型一起改 insert into 表名 values (值1,值2,..);#表中添加数据 select * from 表名;#查看表中数据 insert into 表名 (字段1,字段2,..) values (值1,值2,..);#指定列插入数据 delete from 表名 where 条件;#删除数据 多条:where 字段 in (值..); update 表名 set 列名称 =新值 where 列名称 = 某值;#修改数据 实务操作: set autocommit=0; sql1 sql2 commit(提交) , rollback(回滚); 查询所有的数据 select * from person; select id, name, age from person; select id as "编号", name as "姓名" from person; 查询指定的数据,按照规定对数据进行操作 运算符: where 字段 运算符 值 = > < != >= like 逻辑运算符 and (&&) or(||) 对数据进行排序 order by 字段 排序的类型; select * from perso order by salary asc;//升序 默认 asc 可以省略的 select * from perso order by salary desc;//降序 在什~ ~之间 between 模糊查询 like 显示输出数据 limit 数字 limit 数字1, 数字2; 数字1:偏移量 数字2:个数
第二十九天
查询
方法:
max();
min(); 求一个字段中数据的最小值
avg(); 求一个字段的数据的平均值
sum(); 求一个字段所有数据的和
count(*); 统计当前表中数据有多少个
select max(字段名字) FROM 表名字;
数据约束
默认值 default
非空 not null
如果给一个字段加上了非空,如果添加数据的时候,必须给当前字段赋值。如果不赋值就会报错
唯一 unique
设置字段的唯一性,添加数据的时候,如果添加数据重复的值话会报错。
主键 primary key
主键是唯一的并且是非空的,以后开发中必须每张表都得有且只有一个主键字段
而且主键字段必须和业务逻辑无关
自增长 auto_increment
我们通常希望在每次插入新记录时,自动地创建主键字段的值。
扩展知识点:
当表中的数据有时间的话表字段如何设置
类型 | 格式 | 用途 | 默认值 |
---|---|---|---|
date(出现频率偏高) | YYYY-MM-DD | 2023-04-08 | |
time | HH:MM:SS | 16:45:03 | |
year | YYYY | 2023 | |
datetime | YYYY-MM-DD hh:mm:ss | ||
timestamp(出现频率偏高) | YYYY-MM-DD hh:mm:ss | 2023-04-08 16:47:08 | current_timestamp |