多线程设计模式基础

来源:互联网 发布:opensuse和ubuntu 编辑:程序博客网 时间:2024/06/14 23:40

不变模式

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