CAS 算法
CAS (Compare-And-Swap) 是一种硬件对并发的支持,针对多处理器
操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并
发访问。
CAS 是一种无锁的非阻塞算法的实现。
CAS 包含了 3 个操作数:
需要读写的内存值 V
进行比较的值 A
拟写入的新值 B
当且仅当 V 的值等于 A 时, CAS 通过原子方式用新值 B 来更新 V 的
值,否则不会执行任何操作。
jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。
java.util.concurrent.atomic 包下提供了一些原子操作的常用类:
AtomicBoolean 、 AtomicInteger 、 AtomicLong 、 AtomicReference
AtomicIntegerArray 、 AtomicLongArray
AtomicMarkableReference
AtomicReferenceArray
A:线程池概述
线程池:相当于一个容器,相当于一个装有一定数量的线程对象的容器。
程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。
而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。
线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池
B:内置线程池的使用概述
JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
public static ExecutorService newCachedThreadPool(): 根据任务的数量来创建线程对应的线程个数
public static ExecutorService newFixedThreadPool(int nThreads): 固定初始化几个线程
public static ExecutorService newSingleThreadExecutor(): 初始化一个线程的线程池
这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。它提供了如下方法
Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task)
使用步骤:
创建线程池对象
创建Runnable实例
提交Runnable实例
关闭线程池
C:案例演示: 线程池的使用
public class MyTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
MyRunnable3 myRunnable = new MyRunnable3();
executorService.submit(new MyRunnable3());
executorService.submit(new MyRunnable3());
executorService.submit(new MyRunnable3());
executorService.submit(new MyRunnable3());
executorService.submit(new MyRunnable3());
Future<?> future = executorService.submit(new MyCallable(1000));
Integer o = (Integer) future.get();
System.out.println(o);
Future<Integer> submit = executorService.submit(new MyCallable(100));
Integer integer = (Integer) submit.get();
System.out.println(integer);
executorService.shutdown();
}
}
class MyCallable implements Callable<Integer>{
int num;
public MyCallable(int num){
this.num=num;
}
@Override
public Integer call() throws Exception {
System.out.println("callable任务执行了");
int sum=0;
for (int i = 0; i < num; i++) {
sum+=i;
}
return sum;
}
}
class MyRunnable3 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程任务执行了");
}
}
多线程(匿名内部类的方式实现多线程程序)
A:案例演示
匿名内部类的方式实现多线程程序
new Thread(){代码…}.start();
new Thread(new Runnable(){代码…}).start();
public class MyTest {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
System.out.println("线程运行了");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("第二个线程运行了");
}
}).start();
}
}
多线程(定时器的概述和使用)
A:定时器概述
定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。
在Java中,可以通过Timer和TimerTask类来实现定义调度的功能。
B:Timer和TimerTask
Timer:
public Timer()
public void schedule(TimerTask task, long delay):
public void schedule(TimerTask task,long delay,long period);
public void schedule(TimerTask task, Date time):
public void schedule(TimerTask task, Date firstTime, long period):
TimerTask:定时任务
public abstract void run()
public boolean cancel()
开发中
Quartz是一个完全由java编写的开源调度框架。
C:案例演示: 定时器的使用
public class MyTest {
public static void main(String[] args) {
Timer timer = new Timer();
MytimeTask mytimeTask = new MytimeTask(timer);
// timer.schedule(mytimeTask,5000);
// mytimeTask.cancel();
timer.schedule(mytimeTask,2000,1000);
}
}
class MytimeTask extends TimerTask{
Timer timer;
public MytimeTask(Timer timer) {
this.timer=timer;
}
@Override
public void run() {
System.out.println("砰~爆炸了");
// timer.cancel();
}
}
多线程(定时器的练习)
A:案例演示
定时任务的多次执行代码体现
定时删除指定的带内容目录
public class MyTest {
public static void main(String[] args) throws ParseException {
Timer timer = new Timer();
DelTask delTask = new DelTask(timer);
timer.schedule(delTask,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-04-30 17:16:00"));
}
}
class DelTask extends TimerTask{
Timer timer;
public DelTask(Timer timer) {
this.timer=timer;
}
@Override
public void run() {
File file = new File("C:\\Users\\HP\\Desktop\\新建文件夹");
delFolder(file);
timer.cancel();
}
private void delFolder(File floder) {
File[] files = floder.listFiles();
for (File f : files) {
if (f.isFile()){
f.delete();
}else {
delFolder(f);
}
}
floder.delete();
}
}
A:简单工厂模式概述: 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
B:优点: 使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,
而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品。
明确了类的职责
C:缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,
就需要不断的修改工厂类,不利于后期的维护
D:案例演示
public class MyTest {
public static void main(String[] args) {
Animal animal = AnimalFactory.getAnimal("cat");
animal.eat();
animal = AnimalFactory.getAnimal("dog");
animal.eat();
animal = AnimalFactory.getAnimal("Tiger");
animal.eat();
}
}
工厂:
public class AnimalFactory {
private AnimalFactory() {
}
public static Animal getAnimal(String name){
if ("cat".endsWith(name)){
return new Cat();
}else if ("dog".equals(name)){
return new Dog();
}else if ("Tiger".equals(name)) {
return new Tiger();
}else {
return null;
}
}
}
设计模式(工厂方法模式的概述和使用)
A:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
B:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,
只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
C:缺点: 需要额外的编写代码,增加了工作量
案例演示
public class MyTest {
public static void main(String[] args) {
Animal animal = new CatFactory().createAnimal();
animal.eat();
Animal animal1 = new DogFactory().createAnimal();
animal1.eat();
}
}
public interface BigAnimalFactory {
Animal createAnimal();
}
public class DogFactory implements BigAnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
public class CatFactory implements BigAnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
设计模式(单例模式之懒汉式)
A:案例演示: 单例模式之懒汉式
public class Teacher {
private static Teacher teacher=null;
private Teacher(){}
public static Teacher getTeacher(){
if (teacher==null){
teacher = new Teacher();
}
return teacher;
}
}
B:饿汉式和懒汉式的区别
单例设计模式之懒汉式
开发中 饿汉式
面试中 懒汉式
面试就是想面试你们的两种思想:
a: 线程安全思想
b: 延迟加载思想
设计模式(单例模式的Java代码体现Runtime类)
A:Runtime类概述
每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。
应用程序不能创建自己的 Runtime 类实例。
B:案例演示: public Process exec(String command) //执行Dos 命令
定时关机
public class MyTest {
public static void main(String[] args) throws IOException, ParseException {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("shutdowm -s -t 0");
} catch (IOException e) {
e.printStackTrace();
}
}
},new SimpleDateFormat("HH:mm:ss").parse("12:00:00"));
}
}
C:查看Runtime的源码: 发现是单例模式的应用
设计模式(模版设计模式概述和使用)
A: 需求: 计算一个for循环执行的时间
B:模版设计模式概述
模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
C:优点和缺点
a:优点: 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
b:缺点: 如果算法骨架有修改的话,则需要修改抽象类
D:案例演示: 模版设计模式的使用
public abstract class TestTimeUtils {
public void testTime(){
long start = System.currentTimeMillis();
testHaoShi();
long end = System.currentTimeMillis();
System.out.println("耗时"+(end-start)+"毫秒");
}
public abstract void testHaoShi();
}
public class TestFor extends TestTimeUtils {
@Override
public void testHaoShi() {
for (int i = 0; i < 10000; i++) {
System.out.println("haha");
}
}
}
public class TestCopyFile extends TestTimeUtils {
@Override
public void testHaoShi() {
for (int i = 0; i < 1000000; i++) {
System.out.println("haha");
}
}
}
public class MyTest3 {
public static void main(String[] args) {
TestFor testFor = new TestFor();
testFor.testTime();
TestCopyFile testCopyFile = new TestCopyFile();
testCopyFile.testTime();
}
}
设计模式(装饰模式概述和使用)
A:装饰模式概述: 装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案
B:优点和缺点
a:优点
使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,
并且可以随意的组合这些功能。
b:缺点: 正因为可以随意组合,所以就可能出现一些不合理的逻辑。
C:案例演示: 装饰模式的使用
public class MyTest {
public static void main(String[] args) {
iPhone iphone = new iPhone();
iphone.call();
MusicPhone musicPhone = new MusicPhone(iphone);
musicPhone.call();
VideoPhone videoPhone = new VideoPhone(iphone);
videoPhone.call();
MusicPhone musicPhone1 = new MusicPhone(new VideoPhone(iphone));
musicPhone1.call();
}
}
public interface Phone {
void call();
}
public class iPhone implements Phone {
@Override
public void call() {
System.out.println("打电话");
}
}
public class BzPhone implements Phone {
Phone phone;
public BzPhone(Phone phone) {
this.phone=phone;
}
@Override
public void call() {
phone.call();
}
}
public class MusicPhone extends BzPhone {
public MusicPhone(Phone phone) {
super(phone);
}
@Override
public void call() {
super.call();
System.out.println("听歌曲");
}
}
public class VideoPhone extends BzPhone {
public VideoPhone(Phone phone) {
super(phone);
}
@Override
public void call() {
super.call();
System.out.println("看视频");
}
}
设计模式(观察者模式概述和使用)
A: 案例: 找猎头找工作
B: 观察者 = 订阅者 + 发布者
岗位类 求职者 猎头(注册方法,注销方法,发布方法)
public class MyTest {
public static void main(String[] args) {
WorkMan man = new WorkMan("张三");
WorkMan man2 = new WorkMan("李四");
WorkMan man3 = new WorkMan("王五");
Job javaJob = new Job("Java开发工程师",10000);
Job webJob = new Job("Web开发工程师",10000);
LieTou lieTou = new LieTou();
lieTou.addMan(man);
lieTou.addMan(man2);
lieTou.addMan(man3);
lieTou.addJob(javaJob);
lieTou.addJob(webJob);
lieTou.removeMan(man3);
Job YwJob = new Job("运维开发工程师", 8000);
lieTou.addJob(YwJob);
}
}
public class WorkMan {
public String name;
public WorkMan(String name) {
this.name = name;
}
}
public class LieTou {
private ArrayList<WorkMan> manList=new ArrayList<WorkMan>();
private ArrayList<Job> jobList=new ArrayList<Job>();
public void addMan(WorkMan man){
manList.add(man);
}
public void addJob(Job job){
jobList.add(job);
notify(job);
}
private void notify(Job job) {
for (WorkMan workMan: manList) {
System.out.println(workMan.name+"你好!有一个岗位"+job.jobName+"薪资"+job.sal+"欢迎你前去面试");
}
}
public void removeMan(WorkMan man){
manList.remove(man);
}
}
public class Job {
public String jobName;
public double sal;
public Job(String jobName, double sal) {
this.jobName = jobName;
this.sal = sal;
}
}