多线程设计模式基础

不变模式

  • 一个类的内部状态创建后,在整个生命周期都不会发生变化,就是不变类
  • 不变模式不需要同步
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++;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/buzhbuzh/article/details/78152507