单例设计模式(重要) 保证类在内存中只有一个对象 饿汉式, 空间换时间, 类创建的时候就创建对象, 线程安全的 懒汉式, 双叫单例加载模式, 使用的时候才创建对象, 存在线程安全问题 区别, 饿汉式空间换时间, 懒汉式时间换空间, 多线程访问时, 饿汉式不会创建多个对象, 懒汉式可能创建多个对象 public class Demo1_Singleton { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1); System.out.println(s2 == s1); } } class Singleton{ // 1. 私有化构造函数, 就不能随意实例类了 private Singleton (){} // 2. 创建实例 private static Singleton s = new Singleton(); // 3. 饿汉式 public static Singleton getInstance() { return s; } } class SingletonLazy{ private SingletonLazy (){} private static SingletonLazy s ; public static SingletonLazy getInstance() { if(s == null){ s = new SingletonLazy(); } return s; } } class SingletonFinal{ private SingletonFinal(){} public static final SingletonFinal s = new SingletonFinal(); } Runtime 类 Process exec(String command) throws IOException 执行命令 import java.io.IOException; public class Demo2_Runtime { public static void main(String[] args) throws IOException { Runtime runtime = Runtime.getRuntime(); runtime.exec("ls"); } } Timer ( 可以被ScheduledExecutorService取代 ) 一种工具, 线程用其安排以后在后台线程中执行的任务, 可安排任务执行一次, 或者定期重复执行 private static void demo1() { Timer t = new Timer(); // t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01); // 定时 执行 // 循环执行, 每3秒执行一次 t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date()); } } ScheduledExecutorService Time的缺陷, 单线程多个任务排队, 一个任务执行时间长了, 后面任务受影响, 一个任务挂了, 后面的任务无法执行, 强依赖系统时间, 系统时间更改则会更改 ScheduledExecutorService 多线程, 则没有上述问题 ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 延时initialDelay, 开始周期delay执行 import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Demo3_Timer { public static void main(String[] args) throws InterruptedException { // 一个任务出现 异常, 不影响其他任务 ScheduledExecutorService ses = Executors.newScheduledThreadPool(2); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("===" + Thread.currentThread().getName() + "==="); } } , 0, 3, TimeUnit.SECONDS); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { int i = 1/0; System.out.println("***" + Thread.currentThread().getName() + "***"); } } , 0, 3, TimeUnit.SECONDS); } private static void demo2(){ // 一个任务执行时间长了, 也不会任务其他任务 ScheduledExecutorService ses = Executors.newScheduledThreadPool(2); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("===" + Thread.currentThread().getName() + "==="); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } , 0, 3, TimeUnit.SECONDS); ses.scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("***" + Thread.currentThread().getName() + "***"); } } , 0, 3, TimeUnit.SECONDS); } private static void demo1() { Timer t = new Timer(); // t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01); // 定时 执行 // 循环执行, 每3秒执行一次 t.schedule(new MyTimerTask(), new Date(121,8,13,11,8,01),3000); while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date()); } } } class MyTimerTask extends TimerTask{ @Override public void run() { System.out.println("起来上班"); } } 多个线程的通信(重要) this.notify() 随机唤醒单个等待线程 public class Demo1_Notify { public static void main(String[] args) { Printer p = new Printer(); new Thread(){ @Override public void run() { while (true){ try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer{ private int flag = 1; public void method1() throws InterruptedException { synchronized (this){ if(flag != 1){ this.wait(); } System.out.println("aaaa"); flag = 2; this.notify(); } } public void method2() throws InterruptedException { synchronized (this){ if(flag != 2){ this.wait(); } System.out.println("bbbbbbbb"); flag = 1; this.notify(); } } } 三个或三个以上间的线程通信 public class Demo2_Notify3 { public static void main(String[] args) { Printer2 p = new Printer2(); new Thread(){ @Override public void run() { while (true){ try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true){ try { p.method3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer2{ private int flag = 1; public void method1() throws InterruptedException { synchronized (this){ while (flag != 1){ this.wait(); } System.out.println("aaaa"); flag = 2; this.notifyAll(); } } public void method2() throws InterruptedException { synchronized (this){ while (flag != 2){ this.wait(); } System.out.println("bbbbbbbb"); flag = 3; this.notifyAll(); } } public void method3() throws InterruptedException { synchronized (this){ while (flag != 3){ this.wait(); } System.out.println("cccccccccccccc"); flag = 1; this.notifyAll(); } } } 线程间通信注意的问题 1.在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法 2.为什么wait方法和notify方法定义在Object这类中? 因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中 3.sleep方法和wait方法的区别? a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来 wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待 b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡 wait方法在同步函数或者同步代码块中,释放锁 互斥锁(重要) ReentrantLock Condition import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Demo3_ReentrantLock { public static void main(String[] args) { Printer3 p = new Printer3(); new Thread(){ @Override public void run() { while (true) { try { p.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true) { try { p.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ @Override public void run() { while (true) { try { p.method3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer3{ private int flag = 1; private ReentrantLock r = new ReentrantLock(); Condition c1 = r.newCondition(); Condition c2 = r.newCondition(); Condition c3 = r.newCondition(); public void method1() throws InterruptedException { r.lock(); if (flag != 1){ c1.await(); } System.out.println("aaaa"); flag = 2; c2.signal(); r.unlock(); } public void method2() throws InterruptedException { r.lock(); if (flag != 2){ c2.await(); } System.out.println("bbbbbbbb"); flag = 3; c3.signal(); r.unlock(); } public void method3() throws InterruptedException { r.lock(); if(flag != 3){ c3.await(); } System.out.println("cccccccccccccc"); flag = 1; c1.signal(); r.unlock(); } } 线程组 public class Demo4_ThreadGroup { public static void main(String[] args) { // demo1(); ThreadGroup threadGroup = new ThreadGroup("自造线程组"); Mythread mythread = new Mythread(); Runnable target; Thread t1 = new Thread(threadGroup, mythread); Thread t2 = new Thread(threadGroup,mythread,"线程1"); Thread t3 = new Thread(threadGroup,mythread,"线程2"); System.out.println(t1.getName()); System.out.println(t2.getName()); System.out.println(t3.getName()); System.out.println(t1.getThreadGroup().getName()); System.out.println(t2.getThreadGroup().getName()); System.out.println(t3.getThreadGroup().getName()); System.out.println(t1.getThreadGroup().getParent().getName()); } private static void demo1() { Mythread mythread = new Mythread(); Thread t1 = new Thread(mythread); Thread t2 = new Thread(mythread); ThreadGroup tg1 = t1.getThreadGroup(); ThreadGroup tg2 = t2.getThreadGroup(); System.out.println(tg1.getName()); System.out.println(tg2.getName()); } } class Mythread implements Runnable{ @Override public void run() { } } 线程的5种状态 新建线程.start() -> 线程就绪状态, 有执行权->抢到CPU执行权限执行->死亡状态, run执行完了 抢到CPU执行权限执行->wait或sleep线程阻塞->叫醒线,程线程就绪状态, 有执行权 线程池 程序创建一个线程成本比较高, 为了方便使用线程池, 使用后再返给JVM import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Demo5_Executors { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(2); pool.submit(new Mythread()); pool.submit(new Mythread()); pool.shutdown(); } } 实现Callable的线程 import java.util.concurrent.*; public class Demo6_Callable { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(2); Future<Integer> f1 = pool.submit(new MyCallable(10)); Future<Integer> f2 = pool.submit(new MyCallable(20)); System.out.println(f1.get()); System.out.println(f2.get()); pool.shutdown(); } } class MyCallable implements Callable<Integer>{ private int num; public MyCallable(int num){ this.num = num; } @Override public Integer call() throws Exception { int sum = 0; for(int i=1;i<num;i++){ sum = sum + i; } return sum; } } 简单工厂模式 概述 静态工厂方法模式, 它定义一个具体的工厂类负责创建一些类的实例 优点 客户端不负责对象的创建, 从而明确各类的职责 缺点 静态工厂负责所有类的创建, 如果有新的对象或者新对象创建方式不同, 就需要不断修改工厂类, 不利于后期维护. public abstract class Animal { public void eat(){}; } public class AnimalFactory { public static Dog createDog(){ return new Dog(); } public static Cat createCat(){ return new Cat(); } public static Animal createAnimal(String animal){ if( "dog".equals(animal)){ return new Dog(); } else if( "cat".equals(animal)){ return new Cat(); } return null; } } public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } } public class Dog extends Animal{ @Override public void eat() { System.out.println("单身狗儿吃狗粮"); } } ``
...