首页 > 编程语言 > 详细

多线程:对象的发布(publish)、逸出(escape),逸出解决方案

时间:2020-06-24 16:49:27      阅读:64      评论:0      收藏:0      [点我收藏+]

对象发布(publish)

含义:一个对象可以在当前作用域之外的代码中使用。

发布方式:如懒汉式、饿汉式、工厂模式等发布的对象。

 

代码示例:

package com.bicai.publish;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author lizhengjun
 * @Date 2020/6/24
 * @Desc 发布水果对象(懒汉式)
 */

public class PublishFruit {

    private List<String> fruitList = null;

    /**
     * @description: 发布水果集合对象(注:线程不安全)
     * @return: 水果集合对象
     * @date: 2020/6/24 15:33
     */
    public List<String> getInstance() {
        if(fruitList == null) {
            // 对象数据初始化
            fruitList = new ArrayList<>();
            fruitList.add("apple");
            fruitList.add("orange");
        }
        return fruitList;
    }
}

 

测试:

    public static void main(String[] args) {
        PublishFruit publishFruit = new PublishFruit();
        // 获取水果集合对象
        List<String> fruitList = publishFruit.getInstance();
        System.out.println("水果集合对象:" + fruitList);
    }

 

输出结果:

水果集合对象:[apple, orange]

 

对象逸出(escape)

含义:发布对象内部状态可能会破坏封装性,并使得程序难以维持不变性条件;当某个不应该发布的对象被发布时,这种情况就称为逸出。

 

代码示例:

package com.bicai.publish;

/**
 * @Author lizhengjun
 * @Date 2020/6/24
 * @Desc 对象逸出演示
 */

public class EscapeThread {

    private String taskNumber = "N001";     // 任务编号
    private String taskName = null;    // 任务名称

    public EscapeThread() {
        new Thread(new EatFruitTask()).start();
        new Thread(new EatFruitTask()).start();
        // 初始化任务名称
        taskName = "吃水果";
    }

    private class EatFruitTask implements Runnable {
        @Override
        public void run() {
            String user = Thread.currentThread().getId() + "---" + Thread.currentThread().getName();
            System.out.println(user + ":吃水果...开始");
            System.out.println("任务编号taskNumber:" + taskNumber + ",任务名称taskName:" + taskName);
            System.out.println(user + ":吃水果...结束");
        }
    }
}

 

测试:

    public static void main(String[] args) {
        EscapeThread escapeThread = new EscapeThread();
    }

 

输出结果:

12---Thread-0:吃水果...开始
13---Thread-1:吃水果...开始
任务编号taskNumber:N001,任务名称taskName:null
任务编号taskNumber:N001,任务名称taskName:吃水果
13---Thread-1:吃水果...结束
12---Thread-0:吃水果...结束

 

对象逸出解决方案

代码示例:

/**
 * @Author lizhengjun
 * @Date 2020/6/24
 * @Desc 对象逸出解决方案
 */

public class EscapeThreadSolution {

    private String taskNumber = "N001";     // 任务编号
    private String taskName = null;    // 任务名称

    Thread thread1 = null;
    Thread thread2 = null;

    public EscapeThreadSolution() {
        thread1 = new Thread(new EatFruitTask());
        thread2 = new Thread(new EatFruitTask());
        // 初始化任务名称
        taskName = "吃水果";
    }

    public void startTask() {
        thread1.start();
        thread2.start();;
    }

    private class EatFruitTask implements Runnable {
        @Override
        public void run() {
            String user = Thread.currentThread().getId() + "---" + Thread.currentThread().getName();
            System.out.println(user + ":吃水果...开始");
            System.out.println("任务编号taskNumber:" + taskNumber + ",任务名称taskName:" + taskName);
            System.out.println(user + ":吃水果...结束");
        }
    }
}

 

测试:

    public static void main(String[] args) {
        EscapeThreadSolution escapeThreadSolution = new EscapeThreadSolution();
        escapeThreadSolution.startTask();
    }

 

输出结果:

13---Thread-1:吃水果...开始
12---Thread-0:吃水果...开始
任务编号taskNumber:N001,任务名称taskName:吃水果
12---Thread-0:吃水果...结束
任务编号taskNumber:N001,任务名称taskName:吃水果
13---Thread-1:吃水果...结束

 

解决思路:避免在构造函数里启动线程;

 

温馨提示

导致对象逸出的情况会有很多,如系统资源初始化、上下文初始化等,针对不同情况采用不同的解决方式。

 

多线程:对象的发布(publish)、逸出(escape),逸出解决方案

原文:https://www.cnblogs.com/qiancdd/p/13188124.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!