ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java编码:保证方法调用链的原子性

2020-12-27 15:57:52  阅读:194  来源: 互联网

标签:编码 调用 java cn thread club html lenovo com


保证方法调用链的原子性

如果我们想创建一个对象的实例,而这个对象的实例是通过链式调用创建的。然后我们需要保证链调用的原子性。

请考虑以下示例:

public class ChainedMethod {
private int age=0;
private String name="";
private String adress="";

public ChainedMethod setAdress(String adress) {
    this.adress = adress;
    return this;
}

public ChainedMethod setAge(int age) {
    this.age = age;
    return this;
}

public ChainedMethod setName(String name) {
    this.name = name;
    return this;
}

}

一个非常简单的对象,我们定义了三个属性,每个时间集返回一个对此的引用。
https://club.lenovo.com.cn/thread-6601546-1-1.html
https://club.lenovo.com.cn/thread-6601557-1-1.html
https://club.lenovo.com.cn/thread-6601570-1-1.html
https://club.lenovo.com.cn/thread-6601817-1-1.html
https://club.lenovo.com.cn/thread-6601839-1-1.html
https://club.lenovo.com.cn/thread-6601855-1-1.html
https://club.lenovo.com.cn/thread-6601867-1-1.html
https://club.lenovo.com.cn/thread-6601882-1-1.html
https://club.lenovo.com.cn/thread-6601897-1-1.html
https://club.lenovo.com.cn/thread-6601916-1-1.html
https://club.lenovo.com.cn/thread-6601933-1-1.html
https://club.lenovo.com.cn/thread-6601984-1-1.html
https://club.lenovo.com.cn/thread-6601999-1-1.html
https://club.lenovo.com.cn/thread-6602020-1-1.html
https://club.lenovo.com.cn/thread-6602060-1-1.html
https://club.lenovo.com.cn/thread-6602088-1-1.html
https://club.lenovo.com.cn/thread-6602105-1-1.html
https://club.lenovo.com.cn/thread-6602117-1-1.html
https://club.lenovo.com.cn/thread-6602372-1-1.html
https://club.lenovo.com.cn/thread-6602396-1-1.html
https://club.lenovo.com.cn/thread-6602406-1-1.html
https://club.lenovo.com.cn/thread-6602417-1-1.html
https://club.lenovo.com.cn/thread-6602427-1-1.html
https://club.lenovo.com.cn/thread-6602435-1-1.html
https://club.lenovo.com.cn/thread-6602446-1-1.html
https://club.lenovo.com.cn/thread-6602467-1-1.html
https://club.lenovo.com.cn/thread-6602504-1-1.html
https://club.lenovo.com.cn/thread-6602520-1-1.html
https://club.lenovo.com.cn/thread-6602553-1-1.html
https://club.lenovo.com.cn/thread-6602591-1-1.html
https://club.lenovo.com.cn/thread-6602610-1-1.html
https://club.lenovo.com.cn/thread-6602623-1-1.html
https://club.lenovo.com.cn/thread-6602633-1-1.html
https://club.lenovo.com.cn/thread-6603123-1-1.html
https://club.lenovo.com.cn/thread-6603204-1-1.html
https://club.lenovo.com.cn/thread-6603239-1-1.html
https://club.lenovo.com.cn/thread-6603278-1-1.html
https://club.lenovo.com.cn/thread-6603319-1-1.html
https://club.lenovo.com.cn/thread-6603342-1-1.html
https://club.lenovo.com.cn/thread-6603371-1-1.html
https://club.lenovo.com.cn/thread-6603421-1-1.html
https://club.lenovo.com.cn/thread-6603494-1-1.html
https://club.lenovo.com.cn/thread-6603513-1-1.html
https://club.lenovo.com.cn/thread-6603572-1-1.html
https://club.lenovo.com.cn/thread-6603643-1-1.html
https://club.lenovo.com.cn/thread-6603688-1-1.html
https://club.lenovo.com.cn/thread-6603969-1-1.html
https://club.lenovo.com.cn/thread-6603984-1-1.html
https://club.lenovo.com.cn/thread-6604101-1-1.html
https://club.lenovo.com.cn/thread-6604188-1-1.html
https://club.lenovo.com.cn/thread-6604203-1-1.html
https://club.lenovo.com.cn/thread-6604226-1-1.html
https://club.lenovo.com.cn/thread-6604266-1-1.html
https://club.lenovo.com.cn/thread-6604297-1-1.html
https://club.lenovo.com.cn/thread-6604321-1-1.html
https://club.lenovo.com.cn/thread-6604351-1-1.html
https://club.lenovo.com.cn/thread-6604456-1-1.html
https://club.lenovo.com.cn/thread-6604482-1-1.html
https://club.lenovo.com.cn/thread-6604542-1-1.html
https://club.lenovo.com.cn/thread-6604644-1-1.html
https://club.lenovo.com.cn/thread-6604706-1-1.html
https://club.lenovo.com.cn/thread-6604983-1-1.html
https://club.lenovo.com.cn/thread-6604998-1-1.html
https://club.lenovo.com.cn/thread-6605111-1-1.html
https://club.lenovo.com.cn/thread-6605152-1-1.html
https://club.lenovo.com.cn/thread-6605172-1-1.html
https://club.lenovo.com.cn/thread-6605190-1-1.html
https://club.lenovo.com.cn/thread-6605207-1-1.html
https://club.lenovo.com.cn/thread-6605226-1-1.html
https://club.lenovo.com.cn/thread-6605254-1-1.html
https://club.lenovo.com.cn/thread-6605288-1-1.html
https://club.lenovo.com.cn/thread-6605357-1-1.html
https://club.lenovo.com.cn/thread-6605388-1-1.html
https://club.lenovo.com.cn/thread-6605423-1-1.html
https://club.lenovo.com.cn/thread-6605468-1-1.html
https://club.lenovo.com.cn/thread-6605513-1-1.html
https://club.lenovo.com.cn/thread-6605988-1-1.html
https://club.lenovo.com.cn/thread-6606015-1-1.html
https://club.lenovo.com.cn/thread-6606203-1-1.html
https://club.lenovo.com.cn/thread-6606251-1-1.html
https://club.lenovo.com.cn/thread-6606260-1-1.html
https://club.lenovo.com.cn/thread-6606274-1-1.html
https://club.lenovo.com.cn/thread-6606287-1-1.html
https://club.lenovo.com.cn/thread-6606300-1-1.html
https://club.lenovo.com.cn/thread-6606316-1-1.html
https://club.lenovo.com.cn/thread-6606359-1-1.html
https://club.lenovo.com.cn/thread-6606422-1-1.html
https://club.lenovo.com.cn/thread-6606445-1-1.html
https://club.lenovo.com.cn/thread-6606477-1-1.html
https://club.lenovo.com.cn/thread-6606521-1-1.html
https://club.lenovo.com.cn/thread-6606541-1-1.html
https://club.lenovo.com.cn/thread-6606934-1-1.html
https://club.lenovo.com.cn/thread-6606957-1-1.html
https://club.lenovo.com.cn/thread-6607669-1-1.html
https://club.lenovo.com.cn/thread-6607696-1-1.html
https://club.lenovo.com.cn/thread-6607711-1-1.html
https://club.lenovo.com.cn/thread-6607721-1-1.html
https://club.lenovo.com.cn/thread-6607729-1-1.html
https://club.lenovo.com.cn/thread-6607737-1-1.html
https://club.lenovo.com.cn/thread-6607749-1-1.html
https://club.lenovo.com.cn/thread-6607764-1-1.html
https://club.lenovo.com.cn/thread-6607773-1-1.html
https://club.lenovo.com.cn/thread-6607790-1-1.html
https://club.lenovo.com.cn/thread-6607804-1-1.html
https://club.lenovo.com.cn/thread-6607820-1-1.html
https://club.lenovo.com.cn/thread-6607836-1-1.html
https://club.lenovo.com.cn/thread-6608067-1-1.html
https://club.lenovo.com.cn/thread-6608103-1-1.html
https://mclub.lenovo.com.cn/thread-6592866-1-1.html
https://mclub.lenovo.com.cn/thread-6594212-1-1.html
https://mclub.lenovo.com.cn/thread-6594213-1-1.html
https://mclub.lenovo.com.cn/thread-6594216-1-1.html
https://mclub.lenovo.com.cn/thread-6594217-1-1.html
https://mclub.lenovo.com.cn/thread-6594220-1-1.html
https://mclub.lenovo.com.cn/thread-6594335-1-1.html
https://mclub.lenovo.com.cn/thread-6594337-1-1.html
https://mclub.lenovo.com.cn/thread-6594342-1-1.html
https://mclub.lenovo.com.cn/thread-6594344-1-1.html
https://mclub.lenovo.com.cn/thread-6594349-1-1.html
https://mclub.lenovo.com.cn/thread-6594353-1-1.html
让我们看看如何在多线程环境中调用:

    ChainedMethod chainedMethod= new ChainedMethod();
    Thread t1 = new Thread(() -> chainedMethod.setAge(1).setAdress("www").setName("name1"));
    t1.start();

    Thread t2 = new Thread(() -> chainedMethod.setAge(2).setAdress("www2").setName("name2"));
    t2.start();

因为在多线程环境下,上面设置的方法可能会比较混乱。怎么解决?我们可以首先创建一个本地副本,这是线程安全的,因为它是在本地访问的,最后将副本复制到新创建的实例对象。

主要代码如下:
public class ChainedMethodWithBuilder {
private int age=0;
private String name="";
private String adress="";

public ChainedMethodWithBuilder(Builder builder){
    this.adress=builder.adress;
    this.age=builder.age;
    this.name=builder.name;
}

public static class Builder{
    private int age=0;
    private String name="";
    private String adress="";

    public static Builder newInstance(){
        return new Builder();
    }
    private Builder() {}

    public Builder setName(String name) {
        this.name = name;
        return this;
    }

    public Builder setAge(int age) {
        this.age = age;
        return this;
    }

    public Builder setAdress(String adress) {
        this.adress = adress;
        return this;
    }

    public ChainedMethodWithBuilder build(){
        return new ChainedMethodWithBuilder(this);
    }
}

我们看下怎么调用:
  final ChainedMethodWithBuilder[] builder = new ChainedMethodWithBuilder[1];
    Thread t1 = new Thread(() -> {
        builder[0] =ChainedMethodWithBuilder.Builder.newInstance()
            .setAge(1).setAdress("www").setName("name1")
            .build();});
    t1.start();

    Thread t2 = new Thread(() ->{
        builder[0] =ChainedMethodWithBuilder.Builder.newInstance()
            .setAge(1).setAdress("www").setName("name1")
            .build();});
    t2.start();

因为lambda表达式中使用的变量必须是最终的或最终等价的,所以我们需要构建一个最终数组。

读写64bits的值

在java中,64位长和double被视为两个32位。

因此,64位的一个操作被分成32位的两个操作。这就导致了原子问题。

请考虑以下代码:

public class LongUsage {
private long i =0;

public void setLong(long i){
    this.i=i;
}
public void printLong(){
    System.out.println("i="+i);
}

}

因为long的读写分为两部分,如果在多线程环境中多次调用setLong和printLong的方法,可能会出现问题。

解决方法很简单,长变量或双变量都可以定义为volatile。

private volatile long i = 0;

标签:编码,调用,java,cn,thread,club,html,lenovo,com
来源: https://blog.csdn.net/jhjswe/article/details/111812872

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有