JAVASE基础模块三十八(CAS算法 线程池 离职必备定时器 设计模式 简单工厂模式 抽象工厂模式 单例模式及其类 模板模式)
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关键字保证同步的,这是一种独占锁,也是是悲观锁
public class MyTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
for (int i = 0; i < 5; i++) {
new Thread(myRunnable).start();
}
}
}
class MyRunnable implements Runnable{
//CAS 算法
AtomicInteger num= new AtomicInteger(1);
@Override
public void run() {
while (true){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getI());
}
}
public int getI() {
return num.getAndIncrement();
}
}
线程池
-
概述
程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。 而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。 线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。 在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池
-
使用方法
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实例 关闭线程池
-
代码 创建线程池
import java.util.concurrent.*; public class XianChi { public static void main(String[] args) { ExecutorService e = Executors.newCachedThreadPool(); MyRun m = new MyRun(); e.submit(m); e.submit(new MyRun()); e.submit(new MyRun()); MyCall c = new MyCall(); Future<Integer> u = e.submit(c); try { Integer t = u.get(); System.out.println(t); } catch (InterruptedException interruptedException) { interruptedException.printStackTrace(); } catch (ExecutionException executionException) { executionException.printStackTrace(); } e.shutdown();//正常关闭 //e.shutdownNow();//立即关闭 } } class MyRun implements Runnable { @Override public void run() { System.out.println("AAAAAAAAA线程执行了"); } } class MyCall implements Callable<Integer> { @Override public Integer call() throws Exception { int i = 77; i += 33; return i; } }
运行结果: AAAAAAAAA线程执行了 AAAAAAAAA线程执行了 AAAAAAAAA线程执行了 110
-
匿名内部类的方式开启子线程
public class MyTest {
public static void main(String[] args) {
//匿名内部类的方式开启子线程
new Thread(){
@Override
public void run() {
System.out.println("线程执行了");
}
}.start();
new Thread() {
@Override
public void run() {
System.out.println("线程执行了");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程执行了这个任务");
}
}).start();
}
}
离职必备定时器
-
删库跑路
import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Timer; import java.util.TimerTask; public class DingShi { public static void main(String[] args) { Timer t = new Timer(); //延迟两秒执行 MyTimer m = new MyTimer(t); String d = "2020-08-21 14:56:00"; try { t.schedule(new MyTimer(t), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(d)); } catch (ParseException e) { e.printStackTrace(); } } } class MyTimer extends TimerTask { private Timer t; public MyTimer(Timer t) { this.t = t; } @Override public void run() { File f = new File("C:\\Users\\yllch\\Desktop\\xxx"); del(f); System.out.println("删除成功准备跑路..."); t.cancel(); } private void del(File f) { File[] ff = f.listFiles(); for (File fff : ff) { if (fff.isFile()) { fff.delete(); } else { del(fff); } } f.delete(); } } 运行结果: 删除成功准备跑路...
设计模式
- 概述
- 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编写、代码设计经验的总结
- 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰
- 分类
- 创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式
- 行为型模式(对象的功能): 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式
- 结构型模式(对象的组成): 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式
简单工厂模式
- 概述
- 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
- 优点
- 使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例
- 而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品
- 明确了类的职责
- 缺点
- 这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同
- 就需要不断的修改工厂类,不利于后期的维护
public class JianDanGC {
public static void main(String[] args) {
Animal c = AnimalFactory.createAnimal("cat");
c.eat();
Animal d = AnimalFactory.createAnimal("dog");
d.eat();
}
}
abstract class Animal{
public abstract void eat();
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鲸鱼");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃太阳");
}
}
class AnimalFactory{
public static Animal createAnimal(String name){
if("cat".equals(name)){
return new Cat();
} else if("dog".equals(name)){
return new Dog();
}else {
return null;
}
}
抽象工厂模式
- 概述
- 工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现
- 优点
- 客户端不需要在负责对象的创建,从而明确了各个类的职责
- 如果有新的对象增加 只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
- 缺点
- 需要额外的编写代码,增加了工作量
public class ChouXiang {
public static void main(String[] args) {
Animal c = new CatFactory().createAnimal();
c.eat();
Animal d =new DogFactory().createAnimal();
d.eat();
Animal t =new TigerFactory().createAnimal();
t.eat();
}
}
abstract class Animal{
public abstract void eat();
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鲸鱼");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃太阳");
}
}
class Tiger extends Animal {
@Override
public void eat() {
System.out.println("老虎吃鸡");
}
}
interface BigFactory {
Animal createAnimal();
}
class CatFactory implements BigFactory{
@Override
public Animal createAnimal() {
return new Cat();
}
}
class DogFactory implements BigFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
class TigerFactory implements BigFactory{
@Override
public Animal createAnimal() {
return new Tiger();
}
}
运行结果:
猫吃鲸鱼
狗吃太阳
老虎吃鸡
进程已结束,退出代码0
单例模式
-
懒汉式
- 懒汉式 用的时候造 设计为同步方法 保证多线程环境下也是单例的
- 私有构造
- 提供一个公共的静态方法,来返回我该类的一个实例让外界来用。
- 设计为同步方法,保证多线程环境下也是单例的。
public class DanLi { public static void main(String[] args) { Student s1 = Student.getStudent(); Student s2 = Student.getStudent(); System.out.println(s1 == s2); } } class Student{ private static Student s=null; private Student(){} public synchronized static Student getStudent(){ if (s == null) { s=new Student(); } return s; } } 运行结果: true 进程已结束,退出代码0
-
饿汉式 开发中选用饿汉式
public class Tdg { public static void main(String[] args) { Teacher t1 = Teacher.getTeacher(); Teacher t2 = Teacher.getTeacher(); System.out.println(t1 == t2); } } class Teacher { private static Teacher t=new Teacher(); private Teacher() { } public static Teacher getTeacher(){ return t; } } 运行结果: true 进程已结束,退出代码0
单例模式的类
-
概述
- 每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接
- 可以通过 getRuntime 方法获取当前运行时
- 应用程序不能创建自己的 Runtime 类实例
-
方法摘要
void addShutdownHook(Thread hook) 注册新的虚拟机来关闭钩子。 int availableProcessors() 向 Java 虚拟机返回可用处理器的数目。 Process exec(String command) 在单独的进程中执行指定的字符串命令。 Process exec(String[] cmdarray) 在单独的进程中执行指定命令和变量。 Process exec(String[] cmdarray, String[] envp) 在指定环境的独立进程中执行指定命令和变量。 Process exec(String[] cmdarray, String[] envp, File dir) 在指定环境和工作目录的独立进程中执行指定的命令和变量。 Process exec(String command, String[] envp) 在指定环境的单独进程中执行指定的字符串命令。 Process exec(String command, String[] envp, File dir) 在有指定环境和工作目录的独立进程中执行指定的字符串命令。 void exit(int status) 通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。 long freeMemory() 返回 Java 虚拟机中的空闲内存量。 void gc() 运行垃圾回收器。 long totalMemory() 返回 Java 虚拟机中的内存总量。 void traceInstructions(boolean on) 启用/禁用指令跟踪。 void traceMethodCalls(boolean on) 启用/禁用方法调用跟踪。
- 定时关机
public class MyTest { public static void main(String[] args) throws IOException, ParseException { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { try { Runtime runtime = Runtime.getRuntime(); runtime.exec("shutdown -s -t 0"); } catch (IOException e) { e.printStackTrace(); } } },new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-08-21 16:24:00")); } }
模板模式
-
概述
- 模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
- 优点:使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
- 缺点: 如果算法骨架有修改的话,则需要修改抽象类
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; public class MoBan { public static void main(String[] args) { TestFo t1 = new TestFo(); t1.calc(); TestFil t2 = new TestFil(); t2.calc(); } } abstract class cal { public void calc() { long l = System.currentTimeMillis(); TestTime(); long l1 = System.currentTimeMillis(); System.out.println(); System.out.println("耗时共计:" + (l1 - l) + "毫秒"); } public abstract void TestTime(); } class TestFo extends cal { @Override public void TestTime() { for (int i = 0; i <33; i++) { System.out.print(i); } } } class TestFil extends cal { @Override public void TestTime() { try { Files.copy(Paths.get("src\\com\\westos\\X5\\Tdg.java"), Paths.get("Tdg2.java"), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } } } 运行结果: 耗时共计:2毫秒 耗时共计:109毫秒 进程已结束,退出代码0