5-线程池
线程池的概念本质就是一个能够容纳多个线程的容器,其中的线程可以反复利用,省去了频繁创建线程对象的操作,无需因为反复创建线程对象而消耗过多资源
工作线程(PoolWorker)表示线程池中的线程,在没有任务时处于等待状态,可以循环的执行任务
任务队列(TaskQueue)用于存放没有处理的任务,提供一种缓冲机制
任务接口(Task)每个任务必须实现的接口,一共工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等等
线程池管理器(ThreadPool)用于创建并管理线程。包括:创建线程池,销毁线程池,添加线程或任务等等
线程池创建线程来执行,而Worker执行完之后,就去队列中取未分配的task,调用task的run方法。通俗的讲就是任务来后就分配一个线程使用,线程处于占用状态,如果任务执行完毕,线程归还于线程池,并且暂处于空闲状态
合理利用线程池的好处降低资源消耗减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可以执行多个任务
提高响应速度不需要频繁的创建线程,如果有线程可以直接用,不会出现系统僵死
提高线程的可管理性线程池可以约束系统最多 ...
4-线程通信,线程状态
线程通信多个线程因为在同一个进程中,所以互相通信比较容易
线程通信的经典模型:生产者与消费者问题生产者负责生成商品,消费者负责消费商品,生产不能过剩(仍有数据未被消费时不能生产),消费不能没有(不能消费还没有生产的数据)
模拟案例:两名消费者拥有一个共享账户,共享资源,三名生产者负责生产资源。
两名消费者去获取资源,资源存在就取出,不存在就等待,唤醒生产者继续生产资源。
生产者生产资源时,发现仍然存在资源就不继续生产,如果没有资源就生产,然后等待,唤醒消费者来消费
注意:
线程通信一定是多个线程操作同一个资源才需要进行通信
线程通信必须先保证线程安全,否则毫无意义,代码也会报错
线程通信的Object提供三种核心方法
wait()方法:让当前线程进入等待状态,此方法必须由锁对象调用
notify()方法:唤醒当前锁对象上等待状态的某个线程,此方法必须由锁对象调用
notifyAll()方法:唤醒当前锁对象上等待状态的全部线程,此方法必须由锁对象调用
代码实现账户类,定义了存钱和取钱的操作123456789101112131415161718192021222324252627282 ...
3-多线程安全问题,线程同步
线程安全问题指的是多个线程操作同一个共享资源的时候可能会出现的线程安全问题
银行取钱问题多个用户同时操作一个银行账户进行取钱操作,账户内余额为1000元,每个账户同时取出1000元,由于线程执行的随机性就会导致线程安全问题的产生
银行账户类定义账户内容,定义取钱方法1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950package ThreadSafety;//定义账户类public class Account { private int cardID; private double Money; //定义取钱过程,所有操作这个账户的人都会取走账户中的m元钱 public void DrawMoney(int m){ //判断取钱的用户 String name =Thread.currentThread().getName(); //判断余额是否充足 if(M ...
2-多线程
多线程概述(并发编程)进程程序是静止的,而运行中的程序就是进程
特征
动态性:进程是运行中的程序,要动态的占用内存,CPU和网络等资源
独立性:进程和进程之间是相互独立的,彼此有自己独立内存区域
并发性:假如CPU是单核,同一时刻内存中只有一个进程在被执行,CPU会依时为每个进程服务,由于切换速度非常快,给我们的感觉就是这些进程在同时执行,这就是并发性
并行:同一时刻同时有多个进程在执行(多核CPU)
线程线程属于进程,一个进程可以包含多个线程,这就是多线程。(线程是进程中的一个独立执行单元)线程的创建开销相对于进程来说比较小,线程也支持并发性
作用
提高程序效率,线程支持并发性,可以有更多机会得到CPU
多线程可以解决很多业务模型
大型高并发技术的核心技术
线程创建方式一:继承Thread类代码实现12345678910111213141516171819202122232425262728293031323334353637383940package ThreadTest;/** 创建线程的方法一:* 1. 直接定义类继承Thread* 2. 重写run()方法* 3. 创建线 ...
1-异常
异常的概念异常是程序在“编译”或者“执行”的过程中可能出现的问题
异常应该尽量提前避免,但是无法做到绝对避免,异常的可能情况太多,开发中只能提前干预。
异常一旦出现,如果没有提前避免,程序就会退出JVM虚拟机而终止,开发中异常是需要提前处理的。研究异常,并且避免异常,然后提前处理异常,体现的是程序的安全性,健壮性
Java会为常见的代码异常都设计一个类来代表
Error错误的意思,严重错误Error,无法通过处理的错误,一旦出现,程序员难以进行修改,一般只能重启系统,优化项目。例如:内存崩溃,JVM本身崩溃
Exception异常类,是开发中代码在编译或者执行过程中可能出现的错误,它是需要提前处理的,以便程序更加健壮
编译时异常:继承自Exception的异常或者其子类,编译阶段就会报错,必须程序员进行处理,否则代码编译无法通过
运行时异常,继承自RuntimeException的异常或其子类,编译阶段不报错,运行阶段出现,运行时异常可处理也可不处理
运行时异常常见的运行时异常
数组索引越界异常:ArrayIndexOutOfBoundsException
空指针异常:NullPo ...
9-Spring集成web环境
ApplicationContext应用上下问的获取方式下面是之前一直采用的应用上下问的获取方法
12345678public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); UserService service= (UserService) context.getBean("userService"); service.save(); }}
通过new ClassPathXmlApplicationC ...
8-Spring事务控制
Spring事务控制事务概念
概括来讲,事务是一个由有限操作集合组成的逻辑单元。事务操作包含两个目的,数据一致以及操作隔离。数据一致是指事务提交时保证事务内的所有操作都成功完成,并且更改永久生效;事务回滚时,保证能够恢复到事务执行之前的状态。操作隔离则是指多个同时执行的事务之间应该相互独立,互不影响。
事务是一个比较广泛的概念,事务管理资源除了我们熟知的数据库外,还可以包含消息队列、文件系统等。当然,一般来说,我们说的事务单指“数据库事务”。
事务的ACID属性
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
编程式事务控制Spring编程式事务控制就是指利用Spring提供的API进行事务控制,通过编写J ...
7-JDBCTemplate
JDBCTemplate是Spring框架中的一个对象,是对原始繁琐JDBC API的封装
使用步骤
导入spring-jdbc和spring-tx坐标
创建数据库表和实体
创建JDBCTemplate对象
执行数据库操作
数据库表和实体对象
12345678910111213141516171819202122232425262728public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String passw ...
6-基于XML与注解的AOP开发
XML方式实现AOP实现步骤
导入AOP相关坐标(Spring中AOP主要通过aspectj实现,所以要导入aspectjweaver)
创建目标接口和目标类(内部有切点)
创建切面类(内部实现增强方法)
将目标类和切面类的创建权交给Spring(将目标类和切面类放入Spring容器中)
在applicationContext配置文件中配置织入关系
测试代码
目标类与目标接口123456/** * 目标对象接口 */public interface TargetObject { public String save();}
123456789/** * 目标对象 */public class TargetObjectImpl implements TargetObject{ public String save() { System.out.println("save running..."); return "return value..."; } ...
5-AOP基础
AOP-面向切面编程AOP是Aspect Oriented Programing(面向切面编程)的缩写,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
简言之,在OOP(面向对象编程)中,最大的特点就是继承,多态与封装,而在封装过程中我们需要把功能不同的方法封装到不同对象中,这就导致了我们在使用这些对象时重复度很高,例如有多个方法都需要在执行前调用日志控制方法,我们当前的解决办法只有在每个类中重写日志控制方法或者将日志控制方法写入新的控制类,在需要的类中调用该方法
第一种方法不仅耦合度高,而且不便于重写或修改,代码重复度也很高,第二种方法,虽然解决了代码重写修改的问题,但日志控制方法会与所有调用它的类耦合死,我们调用某一方法时必然会调用与之耦合的日志控制类
基于以上问题,便形成了与之对应的解决方案:面向切面编程AOP,一般 ...