目录
还有获取成员变量和方法的api,没时间了先不看了,原理大差不差
线程
创建
继承thread类
public class m1_extendsThread {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();//执行的还是run
for (int i = 0; i < 5; i++)
System.out.println("main线程输出");
}
}
/*
* 1.定义一个线程类继承线程
* */
class MyThread extends Thread{
//重写run方法
@Override
public void run() {
for (int i = 0; i < 5; i++)
System.out.println("自定义线程");
}
}
@ 不要把主线程任务放在子线程之前了。
这样主线程一直是先跑完的,相当于是一个单线程的效果了@ 继承一个之后继承不了其他,有局限性
重写runnable接口
public class m2_runnable {
public static void main(String[] args) {
MyRun m = new MyRun();
new Thread(m).start();
for (int i = 0; i < 5; i++)
System.out.println("main线程");
}
}
class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++)
System.out.println("子线程输出");
}
}
@ 可以实现多个接口,加继承
@ 但是拿不到run的返回结果
callable接口(jdk5.0)
public class m3_Callable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCall r = new MyCall(100);
FutureTask<String> f1 = new FutureTask<>(r);
Thread t = new Thread(f1);
t.start();
System.out.println(f1.get());
}
}
class MyCall implements Callable<String>{
private int n;
private int sum;
public MyCall(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
for (int i = 0; i <=n; i++) {
sum+=i;
}
return sum+"";
}
}
优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
可以在线程执行完毕后去获取线程执行的结果。
API
县城安全
多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。(取钱,买票············)
问题模拟
public class danger_moni {
public static void main(String[] args) {
Account pool = new Account("alibaba" ,100000);
new DrawThread(pool, "xiaohong").start();
new DrawThread(pool, "xiaoming").start();
}
}
class DrawThread extends Thread{
private Account ac;
public DrawThread(Account account, String name){
super(name);
this.ac = account;
}
@Override
public void run() {
ac.draw(100000);
}
}
class Account{
private String id;
private int money;
public Account(String id, int money) {
this.id = id;
this.money = money;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void draw(int i) {
String name = Thread.currentThread().getName();
if(this.money >= i){
System.out.println("吐了10w to "+name);
this.money-=i;
System.out.println(name+"取完,余额:"+this.money);
}else
System.out.println("余额不足");
this.money-=i;
}
}
线程同步
思想
加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。
同步代码块
同步方法
作用:把出现线程安全问题的核心方法给上锁。
原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
@ 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
@ 如果方法是实例方法:同步方法默认用thS作为的锁对象。但是代码要高度面向对象!
@ 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
Lock对象(jdk5.0)
try {
if(this.money >= i){
System.out.println("吐了10w to "+name);
this.money-=i;
System.out.println(name+"取完,余额:"+this.money);
}else
System.out.println("余额不足");
} catch (Exception e) {
e.printStackTrace();
} finally {
l.unlock();
}
线程通信*
package c4_thread_communication;
public class CommuDemo {
public static void main(String[] args) {
Account ac = new Account("ChinaBank", 0);
// 取钱线程代表
new DrawThread(ac, "xiaoming").start();
new DrawThread(ac, "xiaohong").start();
// 三个存钱线程代表
new SaveThread(ac, "一die").start();
new SaveThread(ac, "2die").start();
new SaveThread(ac, "3die").start();
}
}
class SaveThread extends Thread{
private Account ac;
public SaveThread(Account account, String name){
super(name);
this.ac = account;
}
@Override
public void run() {
while (true) {
ac.save(500000);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
package c4_thread_communication;
public class Account {
private String id;
private int money;
public Account(String id, int money) {
this.id = id;
this.money = money;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public synchronized void draw(int i) {
String name = Thread.currentThread().getName();
try {
if (this.money>=i){
this.money-=i;
System.out.println(name+"取完还有"+money);
//唤醒存钱线程
this.notifyAll();//先唤醒所有进程
this.wait();//再锁对象让当前线程进入等待
}else {
//唤醒存钱线程
this.notifyAll();//先唤醒所有进程
this.wait();//再锁对象让当前线程进入等待
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void save(int i) {
String name = Thread.currentThread().getName();
try {
if (this.money<100){
this.money+=i;
System.out.println(name+"save完还有"+money);
//唤醒存钱线程
this.notifyAll();//先唤醒所有进程
this.wait();//再锁对象让当前线程进入等待
}else {
//唤醒存钱线程
this.notifyAll();//先唤醒所有进程
this.wait();//再锁对象让当前线程进入等待
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package c4_thread_communication;
public class DrawThread extends Thread{
private Account ac;
public DrawThread(Account account, String name){
super(name);
this.ac = account;
}
@Override
public void run() {
while (true) {
ac.draw(100000);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
线程池!!!
线程池就是一个可以复用线程的技术。
@ 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。
API、参数说明
处理Runnable任务
public class PoolDemo0 {
public static void main(String[] args) {
/*
* public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
* */
ExecutorService e = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
Runnable r = new MyRun();
e.execute(r);
e.execute(r);
e.execute(r);//三个线程与任务绑定
e.execute(r);
e.execute(r);
e.execute(r);
e.execute(r);
e.execute(r);//五个进入了任务队列
e.execute(r);//再来创建新线程
e.execute(r);//再来创建新线程
e.execute(r);//再来拒绝新线程
/*
* [Running, pool size = 5, active threads = 5, queued tasks = 5, completed tasks = 0]
* */
e.shutdown();
}
}
class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"输出第"+i);
}
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
处理Callable任务
public class PoolDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService e = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
Future<String> f1 = e.submit(new MyCall(100));
Future<String> f2 = e.submit(new MyCall(200));
Future<String> f3 = e.submit(new MyCall(300));
Future<String> f4 = e.submit(new MyCall(400));
Future<String> f5 = e.submit(new MyCall(500));
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
System.out.println(f5.get());
}
}
class MyCall implements Callable{
private int n;
public MyCall(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 0; i < n; i++) {
sum+=n;
}
return Thread.currentThread().getName()+"结果"+sum;
}
}
Executors工具类构建线程池对象
定时器
创建
//创建定时器对象
Timer t = new Timer();
//执行方法
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
}
}, 3000, 1000);//delay延迟,period周期执行
缺陷1:等待~~~~~~~无法按时执行
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
try {
// 这个县城睡了一会导致下一个
// 县城无法及时按指定时间运行
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, 3000, 1000);//delay延迟,period周期执行
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"BBB"+new Date());
}
}, 3000, 1000);//delay延迟,period周期执行
缺陷3:一个死了全死了
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
System.out.println(10/0);//单线程,这个死了别的正常也死了
}
}, 3000, 1000);//delay延迟,period周期执行
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"BBB"+new Date());
}
}, 3000, 1000);//delay延迟,period周期执行
弥补
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" AAA"+new Date());
try {
Thread.sleep(5000);//这里睡觉不影响下面县城执行
//这里错了死掉也不影响
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, 0, 2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" BBB"+new Date());
}
}, 0, 2, TimeUnit.SECONDS);
线程六个状态*
网络(暂时跳过)
InetAddress
API
单元测试
单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性。
JUnit
JUnit是使用Java语言实现的单元测试框架,它是开源的
此外,几乎所有的IDE工具都集成了Unit,这样我们就可以直接在IDE中编写并运行Unit测试
反射
反射是指对于任何一个Class:类,在"运行的时候"都可以直接得到这个类全部成分。
这种运行时动态获取类信息以及动态调用类中成分的能力称为ava语言的反射机制。
弹幕:类对象是人类,类的对象是人
获取class类的对象
Class c = Class.forName("c2_reflect.Student");
System.out.println(c);
Class c1 = Student.class;
System.out.println(c1);
Student s = new Student();
Class c2 = s.getClass();
System.out.println(c2); //全是class c2_reflect.Student
获取构造器对象
@Test
public void getpub(){
Class c1 = Student.class;
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
}
}
@Test
public void getall(){
Class c2 = Student.class;
Constructor[] constructors = c2.getDeclaredConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
}
}
//定位单个构造器对象,按照参数个数定位,只能取public
@Test
public void getsingle() throws NoSuchMethodException {
Class c3 = Student.class;
Constructor constructor = c3.getConstructor();
System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
}
//定位单个构造器对象,按照参数个数定位,取任何
@Test
public void getallsingle() throws NoSuchMethodException {
Class c4 = Student.class;
Constructor constructor = c4.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
}
获取完做什么
Class c4 = Student.class;
Constructor constructor = c4.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
Student s = (Student) constructor.newInstance("cxk", 20);
System.out.println(s);
//暴力反射,强行打开private的权限
Constructor con_pri = c4.getDeclaredConstructor();//无参构造原来是private权限
System.out.println(con_pri.getName()+" 参数: "+con_pri.getParameterCount());
con_pri.setAccessible(true);
Student s2 = (Student) con_pri.newInstance();
还有获取成员变量和方法的api,没时间了先不看了,原理大差不差
反射作用
绕过编译阶段给集合添加数据
ArrayList<Integer> arr2 =new ArrayList<>();
Class c = arr2.getClass();
Method add = c.getDeclaredMethod("add", Object.class);
boolean rs = (boolean) add.invoke(arr2, "cxk");//加入String
注解
对]ava中类、方法、成员变量做标记,然后进行特殊处理。
自定义注解
元注解
就是注解注解的注解
注解解析
解析???呵,就是把注解里的东西整出来,叫个解析!
public class Anli {
@Test
public void parseClass(){
Class c = BookStore.class;
if (c.isAnnotationPresent(Book.class)){
// Annotation book = c.getDeclaredAnnotation(Book.class);
Book book = (Book)c.getDeclaredAnnotation(Book.class);
System.out.println(book.name());
System.out.println(Arrays.toString(book.authors()));
System.out.println(book.price());
}
}
@Test
public void parseMethod() throws Exception {
Class c = BookStore.class;
Method m = c.getDeclaredMethod("test");
if (m.isAnnotationPresent(Book.class)){
m.invoke(new BookStore());
}
}
}
@Book(name = "《python入门》", price = 90, authors = {"cxk", "moyan"})
class BookStore{
@Book(name = "《三贱客》", price = 60, authors = {"cxk", "moyan"})
public void test(){
System.out.println("test");
}
}
==========================================================
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Book {
String name();
int price() default 100;
String[] authors();
}
注解应用:模拟Junit框架
public class fakeJunit {
@MyTest
public void test1(){
System.out.println("===test1===");
}
public void test2(){
System.out.println("===test2===");
}
@MyTest
public void test3(){
System.out.println("===test3===");
}
public static void main(String[] args) throws Exception{
Class c = fakeJunit.class;
Method[] methods = c.getDeclaredMethods();
for (Method method :
methods) {
if(method.isAnnotationPresent(MyTest.class))
method.invoke(new fakeJunit());
}
}
}
动态代理!!
创建
流程
案例***
Test
public class Test { public static void main(String[] args) { UserService user = new UserServiceImpl();//不走代理 UserService user2 = ProxyUtil.getPro(user);//走代理 System.out.println(user2.login("admin", "123456")); System.out.println(user2.selectUser()); user2.delUser(); } }
UserService
public interface UserService { String login(String uid, String pwd); void delUser(); String selectUser(); }
UserService实现
public class UserServiceImpl implements UserService{ @Override public String login(String uid, String pwd) { // long startTime = System.currentTimeMillis(); String rs = "登录失败!!!"; if ("admin".equals(uid)&&"123456".equals(pwd)) rs = "login success!"; try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } // long endTime = System.currentTimeMillis(); // System.out.println("login 耗时:"+(endTime-startTime)/1000.0+"s"); return rs; } @Override public void delUser() { // long startTime = System.currentTimeMillis(); try { System.out.println("删除中。。。。"); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } // long endTime = System.currentTimeMillis(); // System.out.println("del耗时:"+(endTime-startTime)/1000.0+"s"); } @Override public String selectUser() { // long startTime = System.currentTimeMillis(); String rs = "查询success"; try { Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } // long endTime = System.currentTimeMillis(); // System.out.println("查询耗时:"+(endTime-startTime)/1000.0+"s"); return rs; } }
ProxyUtil
public class ProxyUtil { //这里换成T,啥对象都能统计运行时间 public static UserService getPro(UserService obj){ return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); Object rs = method.invoke(obj, args); long endTime = System.currentTimeMillis(); System.out.println(method.getName()+"耗时:"+(endTime-startTime)/1000.0+"s"); return rs; } }); } }
Me:这个目的还是减少代码冗余,而且可以走代理增强原对象功能,比如:莫名其妙多了个统计时间的功能(和前边的模板模式一样?)
XML
概述
XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。
常作为软件的配置文件
约束
文档约束:是用来限定文件中的标签以及属性应该怎么写。
DTD
schema
①:编写schema约束文档,后缀必须是.xsd,具体的形式到代码中观看。
②:在需要编写的XML文件中导入该schema约束文档
③:按照约束内容编写XML文件的标签。
xml解析
public void parseXMLData() throws DocumentException {
//解析器对象
SAXReader saxReader = new SAXReader();
//xml加载到内存
InputStream is = Demo1.class.getResourceAsStream("/Contacts.xml");
Document document = saxReader.read(is);
//解析
Element root = document.getRootElement();
System.out.println(root.getName());
}
java的相对路径在模块下./src/package/......
检索技术——XPath
@Test
public void parse01() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));
List<Node> name = document.selectNodes("/contactList/contact/name");
for (Node node :
name) {
Element e = (Element) node;
System.out.println(e.getTextTrim());
}
}
@Test
public void parse02() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));
Element root = document.getRootElement();
List<Node> name = root.selectNodes("./contact/name");
for (Node node :
name) {
Element e = (Element) node;
System.out.println(e.getTextTrim());
}
}
@Test
public void parse03() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));
List<Node> name = document.selectNodes("//name");//全文找name,无层级要求
for (Node node :
name) {
Element e = (Element) node;
System.out.println(e.getTextTrim());
}
}
设计模式
工厂
public class factory {
public static void main(String[] args) {
Computer c = creatComputer("huawei");
c.start();
}
//厂里建好了对象
public static Computer creatComputer(String info){
switch (info){
case "huawei":
Computer c = new Huawei();
c.setName("Mate 90");
c.setPrice(9999);
return c;
case "mac":
Computer c2 = new Mac();
c2.setPrice(7999);
c2.setName("Macbook");
return c2;
default:
return null;
}
}
}
class Huawei extends Computer{
@Override
public void start() {
System.out.println(this.getName()+" is a android");
}
}
class Mac extends Computer{
@Override
public void start() {
System.out.println(this.getName()+" is a apple");
}
}
abstract class Computer{
private String name;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public abstract void start();
}
装饰
创建一个新类,包装原始类,从而在新类中提升原来类的功能。
注意修饰类里边的方法返回的是原始类的方法,调用过修饰类之后还会在调用原始类的方法
me:调用完第一层后的抽象类pri inputstream is就是传入的那个原始类fileinstream,回调原始类方法