2 javawubo javawubo 于 2016.05.12 13:40 提问

线程类中可以用静态代码块做初始化静态变量么?这些静态变量会不会有并发问题呢? 2C

public class SalesConfirmationUploadThread extends Thread {
private boolean result = false;
private final SalesConfirmationPipedInputStream input;
private long orderId;
private String pin;
private JingdongStorageService jss;
private static final String CONTENTTYPE = "application/pdf";
private boolean sealFlag = false;
private final FileOutputStream fos;
private String pdfFile;

private static String PFXFILE;
private static String PFXPASS;
private static String SEALIMAGE;
private static   int PAGENO;
private static int PAGEX;
private static int PAGEY;
private static final Logger log = LoggerFactory.getLogger(SalesConfirmationUploadThread.class);
//初始化电子印章类所用参数
static  {
        Properties properties = new Properties();
        try {
            URL sealPfx = SalesConfirmationUploadThread.class.getResource("/test.pfx");
            URL sealGif = SalesConfirmationUploadThread.class.getResource("/sealjdpic.gif");
            if(sealPfx!=null){
                PFXFILE = sealPfx.getPath();
            }
            if(sealPfx!=null){
                SEALIMAGE = sealGif.getPath();
            }
            properties.load(SalesConfirmationUploadThread.class.getResourceAsStream("/project.properties"));
            String retPfxPass = properties.getProperty("pxf.pass");
            String pageNo = properties.getProperty("pageno");
            String pageX = properties.getProperty("pagex");
            String pageY = properties.getProperty("pagey");

            if (StringUtils.isNotBlank(retPfxPass)) {
                PFXPASS = retPfxPass;
            }
            if(StringUtils.isNotBlank(pageNo)){
                PAGENO = Integer.parseInt(pageNo);
            }
            if(StringUtils.isNotBlank(pageX)){
                PAGEX = Integer.parseInt(pageX);
            }
            if(StringUtils.isNotBlank(pageY)){
                PAGEY = Integer.parseInt(pageY);
            }
        } catch (Exception e) {
            log.error("init seal param error is [{}] ",e);
        } finally {
            log.error("pfxPass={"+PFXPASS+"},sealPfx={"+PFXFILE+"},sealGif={"+SEALIMAGE+"},pageNo={"+PAGENO+"},pageX={"+PAGEX+"},pageY={"+PAGEY+"}");
        }
}

public SalesConfirmationUploadThread(final SalesConfirmationPipedInputStream input,final FileOutputStream fos,final String pdfFile,long orderId, String pin, JingdongStorageService jss){
    this.pdfFile =pdfFile;
    this.fos = fos;
    this.input = input;
    this.orderId = orderId;
    this.pin = pin;
    this.jss = jss;
}

@Override
public void run() {
    CallerInfo callerInfo = Profiler.registerInfo("com.jd.auctionplat.soa.threads.SalesConfirmationUploadThread", true, true);
    if(input == null || input.getLength() <= 0){
        log.error("根据订单号:" + orderId + "和用户pin:" + pin + "上传成交确认书时获取的管道输入流为空");
        return;
    }
    log.error("-----开始上传根据订单号:"  + orderId + "和用户pin:" + pin + "生成的成交确认书,长度为:" + input.getLength() + "----" );
    if(jss == null){
        log.error("----上传成交确认书时jss为空----");
    }
    //将成交确认书读入到服务器
    File file = null;
    try{
        byte[] buffer = new byte[2*1024];
        int len=0;
        while((len=input.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
    }catch(Exception e){
        log.error("根据订单号:" + orderId + "和用户pin:" + pin + "上传成交确认书到服务器时出错", e);
    }finally {
        try{
            if(null != fos){
            fos.close();
            }
        }catch (IOException e){
            log.error("关闭文件输出流时出错", e);
        }
        try {
            if(null != input){
                input.close();
            }
        } catch (IOException e) {
            log.error("关闭管道输入流时出错", e);
        }
    }
    //调用工具类加盖印章
    try{
        UTCSeal s = new UTCSeal();
        sealFlag = s.DoSealWithPfx(pdfFile,PAGENO,PAGEX,PAGEY,PFXFILE,PFXPASS,SEALIMAGE);
    }catch (Exception e){
        log.error("调用电子签章失败!",e);
    }

    try {
        //盖章成功,上传云存储
        if(sealFlag){
            file = new File(pdfFile);
            jss.bucket(SalesConfirmationBucketUtils.getBucket()).
                    object(SalesConfirmationBucketUtils.getSalesConfirmationPath(orderId, pin)).
                    entity(file).contentType(CONTENTTYPE).put();
            result = true;
            String url = SalesConfirmationBucketUtils.getSalesConfirmationPath(orderId, pin);
            log.error("生成成交确认书的url :" +url);
        }
    } catch (Exception e) {
        log.error("根据订单号:" + orderId + "和用户pin:" + pin + "上传成交确认书到云存储时出错", e);
    }finally{
        try {
            //删除服务器中成交确认书
            if(null!=file && file.exists()){
                file.delete();
            }
        } catch (Exception e) {
            log.error("根据订单号:" + orderId + "和用户pin:" + pin + "上传成交确认书时关闭管道输入流出错", e);
        }
    }
    log.error("-----成交确认书上传完成,订单号为:"  + orderId + ",用户pin为:" + pin + "----" );
    Profiler.registerInfoEnd(callerInfo);
}

public boolean isResult() {
    return result;
}

}

3个回答

caozhy
caozhy   Ds   Rxr 2016.05.12 13:48

如果静态代码块本身不使用共享的参数,不调用线程不安全的方法,那么没有并发的问题。

javawubo
javawubo 初始化的静态变量是一些 写死到配置文件里的参数 ;这初始化的静态变量 每个线程是共享的,但是 这样会有并发问题么,
大约 2 年之前 回复
k10692081
k10692081   2016.05.12 14:15

这是线程安全的问题
线程不安全的根由是变更全局变量。而且线程不安全会传递,即使用了线程不安全的全局变量或方法都将线程不安全。

全局变量只要没有引用线程不安全的变量以及被线程不安全的方法所变更,都将是安全的。

u014792378
u014792378   2016.05.12 15:15

这样写是没问题的~~

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
静态变量初始化:静态变量和静态代码块初始顺序
在工具类中,通常会初始化一些单例变量,这些变量由于只会初始一次,并不适合放在构造函数中,因此通常选择在静态代码块中执行,那么在一个类中,就会涉及到静态变量和静态代码块的初始化执行顺序问题。 public class Test { private static Test t = new Test(); private static String a = "1"; static {
java中普通变量、静态变量、静态代码块初始化的顺序辨析
1.普通变量的初始化 看如下程序 class Window{ public Window(int maker) { System.out.println("Window("+maker+")"); } } class House{ Window w1 = new Window(1); public House() { System.out.println("House(
静态变量和静态代码块的执行顺序
static { name="zhangsan"; } private static String name=null;上面这段代码,把name打印出来是null private static String name=null;static { name="zhangsan"; } 上面这段代码,把name打印出来是zhangsanstatic { name="zha
static 静态变量和静态代码块的执行顺序
众所周知 在android中static 修饰的会被称之为 静态常量, 静态变量, 静态方法 ,还有就是静态代码块,用static{ // 代码块 非static修饰的方法,变量,常量, 是不能再静态代码块中使用的 } 表示。        static修饰的 是跟着类走的, 而不是跟随对象,这个大家都是知道的。 那么大家是否知道它们之间的运行顺序的关系呢? 今天, 我就给大家简单讲解一下吧。
Java的静态变量,成员变量,静态代码块,构造块的加载顺序
问题的产生来自下面这个链接(http://bbs.csdn.net/topics/391908395)public class StaticTest{ public static void main(String args[]){ staticFunction(); } static StaticTest st = new StaticTest();
java中的静态变量、静态方法与静态代码块区别
我们知道类的生命周期分为装载、连接、初始化、使用和卸载的五个过程。 其中静态代码在类的初始化阶段被初始化。而非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化。 静态变量 可以将静态变量理解为类变量(与对象无关),而实例变量则属于一个特定的对象。 静态变量有两种情况: 静态变量是基本数据类型,这种情况下在类的外部不必创建该类的实例就
JAVA静态变量、静态方法、静态代码块和静态内部类
一、静态变量     1.静态变量使用static修饰     2.静态变量属于类,可以被类及此类的所有对象访问。普通成员变量属于对象,不能被类直接访问     3.静态变量存储在静态方法区,普通成员变量存储在堆区。     4.静态变量随着类的初始化而初始化,普通成员变量随着对象的初始化而初始化。     5.静态变量不被jvm回收,普通成员变量被jvm回收。     6.静态变量可
多线程中局部静态变量初始化的陷阱
    C++当中常常需要一个全局唯一的对象实例,这时候,我们就会想到单件模式。如何实现这一模式?全局变量当然是一个简单可行的方法,然而,这太丑陋。嗯,其实,丑陋倒也罢了,最严重的是它将引诱程序员滥用全局变量,这将导致维护的灾难。    既然全局变量是可能有害的,那么,我们我们把它隐藏一下,放到某个类当中去,作为类的静态数据成员。这看上去不错,我也这么认为。当我们只是简单的需要一个全局对象时,这很
C#静态变量和静态方法的线程安全问题
数据库连接池一定会遇到线程安全问题,连接池可能会被多个线程同时访问,我在写连接池时,连接池是单例模式,参数和方法都是静态的,在测试过程中发现静态方法也会存在线程安全问题,然后通过查阅资料,得到了一些结果:     静态方法内部创建的参数是线程安全的,不同线程调用同一个静态方法时,他们不会共享静态方法内部创建的参数,代码举例如下 public static void Test() { i
谈谈全局变量、静态变量的初始化问题
经常性的在面试和笔记题目中会看到全局变量、静态全局变量、静态变量的存储位置和初始化时间的问题, 一般都能答出来他们存储位置,但可能有很多人不清楚这些变量是什么时候初始化的,下面我们从代码角度来看看,这些变量是什么时候初始化的, 如果在main函数之前初始化,那么又是如何做的。 samplecode定义如下: MyClass g_A; int g_nTest2 = 1; int main