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 初始化的静态变量是一些 写死到配置文件里的参数 ;这初始化的静态变量 每个线程是共享的,但是 这样会有并发问题么,
一年多之前 回复
k10692081
k10692081   2016.05.12 14:15

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

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

u014792378
u014792378   2016.05.12 15:15

这样写是没问题的~~

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!