前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >24(02)多线程锁,线程通讯,线程组,线程池,多线程三种方式,匿名内部类,定时器,设计模式,单例模式,Runtime

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

作者头像
Java帮帮
发布2018-03-16 17:11:39
1K0
发布2018-03-16 17:11:39
举报
(6)多线程实现的第三种方案
代码语言:javascript
复制
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)多线程的面试题

代码语言:javascript
复制
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)匿名内部类的方式实现多线程

代码语言:javascript
复制
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)定时器概述和使用

代码语言:javascript
复制
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)定时器任务多次执行代码体现

代码语言:javascript
复制
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)定时器删除指定带内容目录

代码语言:javascript
复制
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:简单工厂模式

简单工厂模式概述:

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

优点:

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

缺点:

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

代码语言:javascript
复制
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:工厂方法模式

简单工厂模式概述:

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

优点:

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

缺点:

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

代码语言:javascript
复制
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:饿汉式

代码语言:javascript
复制
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:懒汉式

代码语言:javascript
复制
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命令。

代码语言:javascript
复制
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;
 *    }
 * }
 */
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java帮帮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档