1.多线程(单例设计模式)
a:单例设计模式:保证类在内存中只有一个对象。
b:如何保证类在内存中只有一个对象呢?
控制类的创建,不让其他类来创建本类的对象。private
在本类中定义一个本类的对象。Singleton s;
提供公共的访问方式。 public static Singleton getInstance(){return s}
c:单例写法两种:
(1)饿汉式 开发用这种方式。
class Singleton {
private Singleton(){}
private static Singleton s = new Singleton();
public static Singleton getInstance() {
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
(2)懒汉式 面试写这种方式。多线程的问题?
class Singleton {
private Singleton(){}
private static Singleton s;
public static Singleton getInstance() {
if(s == null)
s = new Singleton();
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
(3)第三种格式
class Singleton {
private Singleton() {}
public static final Singleton s = new Singleton();
}
2.多线程(Runtime类)
a:Runtime类是一个单例类
Runtime r = Runtime.getRuntime();
r.exec("shutdown -s -t 300");
r.exec("shutdown -a");
3.多线程(两个线程间的通信)
a:什么时候需要通信
多个线程并发执行时, 在默认情况下CPU是随机切换线程的。
如果我们希望他们有规律的执行, 就可以使用通信, 例如每个线程执行一次打印。
b:怎么通信
如果希望线程等待, 就调用wait()。
如果希望唤醒等待的线程, 就调用notify()。
这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用。
4.多线程(三个或三个以上间的线程通信)
a:多个线程通信的问题。
notify()方法是随机唤醒一个线程。
notifyAll()方法是唤醒所有线程。
JDK5之前无法唤醒指定的一个线程。
如果多个线程之间通信, 需要使用notifyAll()通知所有线程, 用while来反复判断条件。
5.多线程(线程间的通信注意的问题)
a:在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
b:为什么wait方法和notify方法定义在Object这个类中?
锁对象可以是任意对象,那么任意对象对应的类都是Object类的子类。
也就是Object是所有的类的基类,所以将将方法定义在Object这个类中就会让任意对象对其调用所以wait方法和notify方法需要定义在Object这个类中。
c:sleep方法和wait方法的区别?
sleep在同步代码块或者同步函数中,不释放锁。
wait在同步代码块或者同步函数中,释放锁。
sleep方法必须传入参数,参数其实就是时间,时间到了自动醒来。
wait方法可以传入参数,也可以不传入参数。
如果给wait方法传入时间参数,用法与sleep相似,时间到就停止等待(通常用的都是没有参数的wait方法)。
6.多线程(JDK1.5的新特性互斥锁)
a:同步
使用ReentrantLock类的lock()和unlock()方法进行同步。
b:通信
使用ReentrantLock类的newCondition()方法可以获取Condition对象。
需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法。
不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了。
7.多线程(线程组的概述和使用)
a:线程组概述
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
默认情况下,所有的线程都属于主线程组。
public final ThreadGroup getThreadGroup()
public final String getName()
b:我们也可以给线程设置分组
ThreadGroup(String name) 创建线程组对象并给其赋值名字。
创建线程对象。
Thread(ThreadGroup?group, Runnable?target, String?name)。
设置整组的优先级或者守护线程。
8.多线程(线程池的概述和使用)
a:线程池概述
程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池。
b:内置线程池的使用概述
DK5新增了一个Executors工厂类来产生线程池,有如下几个方法。
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实例。
9.设计模式(简单工厂模式概述和使用)
a:简单工厂模式概述
又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例。
b:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责。
c:缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护。
10.设计模式(工厂方法模式的概述和使用)
a:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
b:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性。
c:缺点
需要额外的编写代码,增加了工作量。
本文为头条号作者发布,不代表今日头条立场。