专栏首页Java帮帮-微信公众号-技术文章全总结24(02)多线程锁,线程通讯,线程组,线程池,多线程三种方式,匿名内部类,定时器,设计模式,单例模式,Runtime

24(02)多线程锁,线程通讯,线程组,线程池,多线程三种方式,匿名内部类,定时器,设计模式,单例模式,Runtime

(6)多线程实现的第三种方案
package cn.itcast_09;(1)
import java.util.concurrent.Callable;
//Callable:是带泛型的接口。
//这里指定的泛型其实是call()方法的返回值类型。
public class MyCallable implements Callable {
 @Override
 public Object call() throws Exception {
 for (int x = 0; x < 100; x++) {
 System.out.println(Thread.currentThread().getName() + ":" + x);
 }
 return null;
 }
}
package cn.itcast_09;(2)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
 * 多线程实现的方式3:
 *   A:创建一个线程池对象,控制要创建几个线程对象。
 *  public static ExecutorService newFixedThreadPool(int nThreads)
 *  B:这种线程池的线程可以执行:
 *  可以执行Runnable对象或者Callable对象代表的线程
 *  做一个类实现Runnable接口。
 *  C:调用如下方法即可
 *  Future<?> submit(Runnable task)
 * <T> Future<T> submit(Callable<T> task)
 * D:我就要结束,可以吗?
 * 可以。
 */
public class CallableDemo {
 public static void main(String[] args) {
 //创建线程池对象
 ExecutorService pool = Executors.newFixedThreadPool(2);
 //可以执行Runnable对象或者Callable对象代表的线程
 pool.submit(new MyCallable());
 pool.submit(new MyCallable());
 //结束
 pool.shutdown();
 }
}

(7)多线程的面试题

package cn.itcast_10;(1)
import java.util.concurrent.Callable;
/*
 * 线程求和案例
 */
public class MyCallable implements Callable<Integer> {
 private int number;
 public MyCallable(int number) {
 this.number = number;
 }
 @Override
 public Integer call() throws Exception {
 int sum = 0;
 for (int x = 1; x <= number; x++) {
 sum += x;
 }
 return sum;
 }
}
package cn.itcast_10;(2)
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/*
 * 多线程实现的方式3:
 *   A:创建一个线程池对象,控制要创建几个线程对象。
 *  public static ExecutorService newFixedThreadPool(int nThreads)
 *  B:这种线程池的线程可以执行:
 *  可以执行Runnable对象或者Callable对象代表的线程
 *  做一个类实现Runnable接口。
 *  C:调用如下方法即可
 *  Future<?> submit(Runnable task)
 * <T> Future<T> submit(Callable<T> task)
 * D:我就要结束,可以吗?
 * 可以。
 */
public class CallableDemo {
 public static void main(String[] args) throws InterruptedException, ExecutionException {
 // 创建线程池对象
 ExecutorService pool = Executors.newFixedThreadPool(2);
 // 可以执行Runnable对象或者Callable对象代表的线程
 Future<Integer> f1 = pool.submit(new MyCallable(100));
 Future<Integer> f2 = pool.submit(new MyCallable(200));
 // V get()
 Integer i1 = f1.get();
 Integer i2 = f2.get();
 System.out.println(i1);
 System.out.println(i2);
 // 结束
 pool.shutdown();
 }
}

(8)匿名内部类的方式实现多线程

package cn.itcast_11;
/*
 * 匿名内部类的格式:
 *  new 类名或者接口名() {
 *  重写方法;
 *  };
 *  本质:是该类或者接口的子类对象。
 */
public class ThreadDemo {
 public static void main(String[] args) {
 // 继承Thread类来实现多线程
 new Thread() {
 public void run() {
 for (int x = 0; x < 100; x++) {
 System.out.println(Thread.currentThread().getName() + ":"
 + x);
 }
 }
 }.start();
 // 实现Runnable接口来实现多线程
 new Thread(new Runnable() {
 @Override
 public void run() {
 for (int x = 0; x < 100; x++) {
 System.out.println(Thread.currentThread().getName() + ":"
 + x);
 }
 }
 }) {
 }.start();
 // 更有难度的
 new Thread(new Runnable() {
 @Override
 public void run() {
 for (int x = 0; x < 100; x++) {
 System.out.println("hello" + ":" + x);
 }
 }
 }) {
 public void run() {
 for (int x = 0; x < 100; x++) {
 System.out.println("world" + ":" + x);
 }
 }
 }.start();
 }
}

(9)定时器概述和使用

package cn.itcast_12;
import java.util.Timer;
import java.util.TimerTask;
/*
 * 定时器:可以让我们在指定的时间做某件事情,还可以重复的做某件事情。
 * 依赖Timer和TimerTask这两个类:
 * Timer:定时
 *  public Timer()
 *  public void schedule(TimerTask task,long delay)
 *  public void schedule(TimerTask task,long delay,long period)
 *  public void cancel()
 * TimerTask:任务
 */
public class TimerDemo {
 public static void main(String[] args) {
 // 创建定时器对象
 Timer t = new Timer();
 // 3秒后执行爆炸任务
 // t.schedule(new MyTask(), 3000);
 //结束任务
 t.schedule(new MyTask(t), 3000);
 }
}
// 做一个任务
class MyTask extends TimerTask {
 private Timer t;
 public MyTask(){}
 public MyTask(Timer t){
 this.t = t;
 }
 @Override
 public void run() {
 System.out.println("beng,爆炸了");
 t.cancel();
 }
}

(10)定时器任务多次执行代码体现

package cn.itcast_12;
import java.util.Timer;
import java.util.TimerTask;
/*
 * 定时器:可以让我们在指定的时间做某件事情,还可以重复的做某件事情。
 * 依赖Timer和TimerTask这两个类:
 * Timer:定时
 *  public Timer()
 *  public void schedule(TimerTask task,long delay)
 *  public void schedule(TimerTask task,long delay,long period)
 *  public void cancel()
 * TimerTask:任务
 */
public class TimerDemo2 {
 public static void main(String[] args) {
 // 创建定时器对象
 Timer t = new Timer();
 // 3秒后执行爆炸任务第一次,如果不成功,每隔2秒再继续炸
 t.schedule(new MyTask2(), 3000, 2000);
 }
}
// 做一个任务
class MyTask2 extends TimerTask {
 @Override
 public void run() {
 System.out.println("beng,爆炸了");
 }
}

(11)定时器删除指定带内容目录

package cn.itcast_12;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/*
 * 需求:在指定的时间删除我们的指定目录(你可以指定c盘,但是我不建议,我使用项目路径下的demo)
 */
class DeleteFolder extends TimerTask {
 @Override
 public void run() {
 File srcFolder = new File("demo");
 deleteFolder(srcFolder);
 }
 // 递归删除目录
 public void deleteFolder(File srcFolder) {
 File[] fileArray = srcFolder.listFiles();
 if (fileArray != null) {
 for (File file : fileArray) {
 if (file.isDirectory()) {
 deleteFolder(file);
 } else {
 System.out.println(file.getName() + ":" + file.delete());
 }
 }
 System.out.println(srcFolder.getName() + ":" + srcFolder.delete());
 }
 }
}
public class TimerTest {
 public static void main(String[] args) throws ParseException {
 Timer t = new Timer();
 String s = "2014-11-27 15:45:00";
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Date d = sdf.parse(s);
 t.schedule(new DeleteFolder(), d);
 }
}

(12)扩展:多线程常见的面试题

A.多线程有几种实现方案,分别是哪几种?

两种。

继承Thread类

实现Runnable接口

扩展一种:实现Callable接口。这个得和线程池结合。

B.同步有几种方式,分别是什么?

两种。

同步代码块

同步方法

C.启动一个线程是run()还是start()?它们的区别?

start();

run():封装了被线程执行的代码,直接调用仅仅是普通方法的调用

start():启动线程,并由JVM自动调用run()方法

D.sleep()和wait()方法的区别

sleep():必须指时间;不释放锁。

wait():可以不指定时间,也可以指定时间;释放锁。

E.为什么wait(),notify(),notifyAll()等方法都定义在Object类中

因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。

而Object代码任意的对象,所以,定义在这里面。

F.线程的生命周期图

新建 -- 就绪 -- 运行 -- 死亡

新建 -- 就绪 -- 运行 -- 阻塞 -- 就绪 -- 运行 -- 死亡

建议:画图解释。

2:设计模式(理解)

(1)面试对象的常见设计原则

单一

其实就是开发人员经常说的”高内聚,低耦合”

也就是说,每个类应该只有一个职责,对外只能提供一种功能,

而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则。

开闭

核心思想是:一个对象对扩展开放,对修改关闭。

其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码。

也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,

如何能够做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,

而具体的实现则是可以改变和扩展的。

里氏

核心思想:在任何父类出现的地方都可以用它的子类来替代。

其实就是说:同一个继承体系中的对象应该有共同的行为特征。

依赖注入

核心思想:要依赖于抽象,不要依赖于具体实现。

其实就是说:在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。

为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。

接口分离原则

核心思想:不应该强迫程序依赖它们不需要使用的方法。

其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。

迪米特

核心思想:一个对象应当对其他对象尽可能少的了解

其实就是说:降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部工作原理,

它可以使各个模块耦合度降到最低,促进软件的复用

(2)设计模式概述和分类

 A:经验的总结

 B:三类

    创建型  创建对象

    结构型  对象的组成

    行为型  对象的功能

(3)改进的设计模式

 A:简单工厂模式

简单工厂模式概述:

又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例

优点:

客户端不需要在负责对象的创建,从而明确了各个类的职责

缺点:

这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护

package cn.itcast_01;(1)
public abstract class Animal {
 public abstract void eat();
}
package cn.itcast_01;(2)
public class Dog extends Animal {
 @Override
 public void eat() {
 System.out.println("狗吃肉");
 }
}
package cn.itcast_01;(3)
public class Cat extends Animal {
 @Override
 public void eat() {
 System.out.println("猫吃鱼");
 }
}
package cn.itcast_01;(4)
public class AnimalDemo {
 public static void main(String[] args) {
 // 具体类调用
 Dog d = new Dog();
 d.eat();
 Cat c = new Cat();
 c.eat();
 System.out.println("------------");
 // 工厂有了后,通过工厂给造
 // Dog dd = AnimalFactory.createDog();
 // Cat cc = AnimalFactory.createCat();
 // dd.eat();
 // cc.eat();
 // System.out.println("------------");
 // 工厂改进后
 Animal a = AnimalFactory.createAnimal("dog");
 a.eat();
 a = AnimalFactory.createAnimal("cat");
 a.eat();
 // NullPointerException
 a = AnimalFactory.createAnimal("pig");
 if (a != null) {
 a.eat();
 } else {
 System.out.println("对不起,暂时不提供这种动物");
 }
 }
}
package cn.itcast_01;(5)
public class AnimalFactory {
 private AnimalFactory() {
 }
 // public static Dog createDog() {
 // return new Dog();
 // }
 //
 // public static Cat createCat() {
 // return new Cat();
 // }
 public static Animal createAnimal(String type) {
 if ("dog".equals(type)) {
 return new Dog();
 } else if ("cat".equals(type)) {
 return new Cat();
 } else {
 return null;
 }
 }
}

 B:工厂方法模式

简单工厂模式概述:

又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例

优点:

客户端不需要在负责对象的创建,从而明确了各个类的职责

缺点:

这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护

package cn.itcast_02;(1)
public abstract class Animal {
 public abstract void eat();
}
package cn.itcast_02;(2)
public interface Factory {
 public abstract Animal createAnimal();
}
package cn.itcast_02;(3)
public class AnimalDemo {
 public static void main(String[] args) {
 // 需求:我要买只狗
 Factory f = new DogFactory();
 Animal a = f.createAnimal();
 a.eat();
 System.out.println("-------");
 //需求:我要买只猫
 f = new CatFactory();
 a = f.createAnimal();
 a.eat();
 }
}
package cn.itcast_02;(4)
public class Dog extends Animal {
 @Override
 public void eat() {
 System.out.println("狗吃肉");
 }
}
package cn.itcast_02;(5)
public class DogFactory implements Factory {
 @Override
 public Animal createAnimal() {
 return new Dog();
 }
}
package cn.itcast_02;(6)
public class Cat extends Animal {
 @Override
 public void eat() {
 System.out.println("猫吃鱼");
 }
}
package cn.itcast_02;(7)
public class CatFactory implements Factory {
 @Override
 public Animal createAnimal() {
 return new Cat();
 }
}

 C:单例模式(掌握)

a:饿汉式

package cn.itcast_03;(1)
public class Student {
 // 构造私有
 private Student() {
 }
 // 自己造一个
 // 静态方法只能访问静态成员变量,加静态
 // 为了不让外界直接访问修改这个值,加private
 private static Student s = new Student();
 // 提供公共的访问方式
 // 为了保证外界能够直接使用该方法,加静态
 public static Student getStudent() {
 return s;
 }
}
package cn.itcast_03;(2)
/*
 * 单例模式:保证类在内存中只有一个对象。
 * 
 * 如何保证类在内存中只有一个对象呢?
 *  A:把构造方法私有
 *  B:在成员位置自己创建一个对象
 *  C:通过一个公共的方法提供访问
 */
public class StudentDemo {
 public static void main(String[] args) {
 // Student s1 = new Student();
 // Student s2 = new Student();
 // System.out.println(s1 == s2); // false
 // 通过单例如何得到对象呢?
 // Student.s = null;
 Student s1 = Student.getStudent();
 Student s2 = Student.getStudent();
 System.out.println(s1 == s2);
 System.out.println(s1); // null,cn.itcast_03.Student@175078b
 System.out.println(s2);// null,cn.itcast_03.Student@175078b
 }
}

b:懒汉式

package cn.itcast_03;(1)
/*
 * 单例模式:
 *  饿汉式:类一加载就创建对象
 *  懒汉式:用的时候,才去创建对象
 * 
 * 面试题:单例模式的思想是什么?请写一个代码体现。
 * 
 *  开发:饿汉式(是不会出问题的单例模式)
 *  面试:懒汉式(可能会出问题的单例模式)
 *  A:懒加载(延迟加载) 
 *  B:线程安全问题
 *  a:是否多线程环境 是
 *  b:是否有共享数据 是
 *  c:是否有多条语句操作共享数据  是
 */
public class Teacher {
 private Teacher() {
 }
 private static Teacher t = null;
 public synchronized static Teacher getTeacher() {
 // t1,t2,t3
 if (t == null) {
 //t1,t2,t3
 t = new Teacher();
 }
 return t;
 }
}
package cn.itcast_03;(2)
public class TeacherDemo {
 public static void main(String[] args) {
 Teacher t1 = Teacher.getTeacher();
 Teacher t2 = Teacher.getTeacher();
 System.out.println(t1 == t2);
 System.out.println(t1); // cn.itcast_03.Teacher@175078b
 System.out.println(t2);// cn.itcast_03.Teacher@175078b
 }
}

(4)Runtime

JDK提供的一个单例模式应用的类。

还可以调用dos命令。

package cn.itcast_03;
import java.io.IOException;
/*
 * Runtime:每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
 * exec(String command)
 */
public class RuntimeDemo {
 public static void main(String[] args) throws IOException {
 Runtime r = Runtime.getRuntime();
// r.exec("winmine");
 // r.exec("notepad");
 // r.exec("calc");
// r.exec("shutdown -s -t 10000");
 r.exec("shutdown -a");
 }
}
/*
 * class Runtime {
 *  private Runtime() {}
 *  private static Runtime currentRuntime = new Runtime();
 *  public static Runtime getRuntime() {
 *        return currentRuntime;
 *    }
 * }
 */

本文分享自微信公众号 - Java帮帮(javahelp)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-12-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java基础-day11-接口;多态案例练习

    Java基础-day11-接口&多态案例练习 题目要求1(多态): 定义家类 方法:饲养动物 动物类: 属性:年龄、姓名 方法:吃饭、睡觉 猫类、狗类、猪类均为...

    Java帮帮
  • Java基础-day10-代码题-继承&抽象类

    Java基础-day10-代码题-继承&抽象类 1.门类继承题: 编写代码,实现如下功能: (1)定义一个门类, 包含3个属性:宽度width 和 高度hei...

    Java帮帮
  • 第十一天 面向对象-接口多态【悟空教程】

    Java帮帮
  • 快速掌握模板方法模式

    模板模式就是定义一个操作中的算法骨架,然后将一些步骤延迟到子类中。模板方法使得子类在不改变算法的结构即可重定义该算法的某些步骤。

    田维常
  • ASP.NET Web API中的依赖注入什么是依赖注入ASP.NET Web API依赖解析器使用Unity解析依赖配置依赖解析

    什么是依赖注入     依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型...

    小白哥哥
  • 设计模式之行为型模式

    将一个请求封装成一个对象 ,从而使我们可用不同请求对客户进行参数化 :对请求排队或记录请求日志 ,以及支持可撤销的操作 .也叫: 动作Action模式 ,事务t...

    时间静止不是简史
  • 设计模式学习 - 工厂模式

    根据不同的对象,提供不同的工厂,然后由客户端来选择对应的工厂。这也是与简单工厂模式的不同的地方。

    许杨淼淼
  • Spring Boot 2.X(十八):集成 Spring Security-登录认证和权限控制

    在企业项目开发中,对系统的安全和权限控制往往是必需的,常见的安全框架有 Spring Security、Apache Shiro 等。本文主要简单介绍一下 Sp...

    朝雾轻寒
  • 工厂模式

    在23中设计模式中,工厂方法属于创建型的设计模式,只有工厂方法和抽象工厂两种,但是实际我们常与简单工厂混淆,因为简单工厂模式违背了开闭原则。

    胖虎
  • Java泛型基础(一)目的泛型类总结

    利用Java开发的时候,肯定会有一个类持有另一个或几个类的情况,在编写一些比较基础的组件,例如缓存操作组件,这类组件的逻辑差不多,但是希望能够处理不同的类型。

    阿杜

扫码关注云+社区

领取腾讯云代金券