不变模式
- 一个类的内部状态创建后,在整个生命周期都不会发生变化,就是不变类
- 不变模式不需要同步
public final class Product{
//确保无子类
private final String no;
//私有属性,不会被其他对象获取
private final String name;
//final属性保证不会被两次赋值
private final double price;
public Product(//参数){
//赋值省略
}
//....生成get()方法
}
不变模式的例子:
String
Boolean
Byte
Character
Double
Float
Integer
Long
Short
Future模式
核心思想是异步调用
模块
- 接口Data
public interface Data{
public String getResult();
}
- Data实现类FutureData,构造很快,但是是一个虚拟的数据,需要装配RealData
//FutureData
public class FutureData implements Data{
producted RealData realdata = null;
producted boolean isReady = false;
public synchronized void setRealData(RealData realdata){
if(isReady)
return;
this.realdata = realdata;
isReady = true; //RealData已经被注入了,通知getResult()
notifyAll();
}
public synchronized String getResult(){
while(!isReady){ //会等待RealData构造完成
try{
wait(); //一直等待,直到RealData被注入完成
}catch(Exception e){
}
}
return realdata.result;
}
}
- Data的实现类ReadData,这是真实数据,其构造比较慢
public class RealData implements Data{
protected final String result;
public RealData(String para){
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 10; i++){
sb.append(para);
sleep(1000); //模拟一个很慢的操作
}
result = sb.toString();
}
public String getResult(){
return result;
}
}
- Client端
public class Client{
public Data request(final String queryStr){
final FutureData future = new FutureData();
new Thread(){
public void run(){
//RealData的构建很慢
//所以在单独的线程中进行
RealData realdata = new RealData(queryStr);
future.setRealData(realdata);
}
}.start();
return future; //FutureData会被立即返回
}
}
- main方法调用
package Future;
public class Main {
public static void main(String[] args) {
Client client = new Client();
//这里会立即返回,因为得到是FutureData,不是RealData
Data data = client.request("name");
System.out.println("请求完毕");
try {
//这里可以用一个sleep代替了对其他业务的处理
//在处理业务的逻辑中,RealData被创建,从而充分利用了等待时间
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//使用真实的数据
System.out.println("数据 = "+data.getResult());
}
}
在其中,使用了装饰者设计模式(RealData和FutureData之间)
- Futrue模式的总结
Future模式的角色有
main系统系统,调用Client发出请求
Client:返回Data对象,立刻返回FutureData对象,并且开启线程去获取RealData
Data:返回数据的接口
FutureData:虚拟数据,返回很快,需要装载RealData。
RealData:真实数据。
单例模式
饿汉模式
public class SingleTon {
//构造私有化
private SingleTon() {}
private static SingleTon instance = new SingleTon();
private static SingleTon getSingleTon() {
return instance;
}
}
优点:线程安全
缺点:无法控制实例何时产生
懒汉模式
public class LazySingleTon {
private LazySingleTon() {}
private static LazySingleTon instance = null;
public static synchronized LazySingleTon getInstance() {
if(instance == null)
instance = new LazySingleTon();
return instance;
}
}
线程不安全,访问需要锁。
线程安全不加锁的懒汉模式
public class StaticSIngleton {
private StaticSIngleton() {
}
/*
* 定义一个静态内部类,用来实例化单例对象
* */
private static class SingletonHolder{
private static StaticSIngleton instance = new StaticSIngleton();
}
public static StaticSIngleton getInstance() {
return SingletonHolder.instance;
}
}
生成者和消费者
生产者产生数据,消费者消耗数据。
步骤
第一步:在外界设置一个对象,通过构造函数传送个给生产者。
第二步:生产者设置对象内容
第三步:消费者获取数据内容
Main方法设置一个对象
public class StudentDemo{
public static void main(String[] args){
//创建资源
Student s = new Student();
//设置获取的类
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
st.start();
gt.start();
}
}
Student类
public class Student{
private String name;
private int age;
private boolean flag; //默认是false,没有数据
public synchronized void set(String name, int age){
//如果有数据,就等待
if(this.flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//设置数据
this.name = name;
this.age = age;
//修改标记
this.flag = true;
//通知消费者
this.notify();
}
public synchronized void get(){
if(!this.flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//获取数据
System.out.println(this.name + "---" + this.age);
//修改标记
this.flag = false;
this.notify();
}
}
消费者
public class GetThread implements Runnable{
private Students s;
public GetThread(Student s){
this.s = s;
}
public void run(){
while(true){
s.get();
}
}
}
生产者
public class SetThread implements Runnable{
private Student s;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
if (x % 2 == 0) {
s.set("林青霞", 27);
} else {
s.set("刘意", 30);
}
x++;
}
}
}