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

问题描述

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

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;
}

}

解决方案

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

解决方案二:

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

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

解决方案三:

这样写是没问题的~~

时间: 2024-08-04 08:17:57

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

java-怎么获取一个JAVA类中各个方法的代码块

问题描述 怎么获取一个JAVA类中各个方法的代码块 特殊需求:获取一个JAVA类中各个方法的代码块来查找方法中是否包含某个关键字,现在通过发射只能拿到方法的属性和注释,有没有API或者其他方法,求告知,3Q 没金币了..对不起大家 PS:获取本地源代码的,不是运行时的class 解决方案 myeclipse中调试调用带有静态代码块的类时出现java.lang.NoClassDefFoundError的处理方法在DWR中实现直接获取一个JAVA类的返回值的两种方法java代码获取当前类类名.方法名

深入浅析Java中普通代码块、构造代码块与静态代码块_java

//执行顺序:(优先级从高到低.) 静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1.普通代码块 public static void main(String[] args) { /*普通代码块: *直接定义在在方法或语句中出现"{普通代码的执行语句}"的就称为普通代码块. *普通代码块执行顺序由他们在代码中出现的次序决定--"先出现先执行" * */ { System.out.p

Java中的static静态代码块的使用详解_java

一.与静态方法的比较 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,静态方法在类加载的时候 就已经加载 可以用类名直接调用 比如main方法就必须是静态的 这是程序入口.两者的区别就是:静态代码块是自动执行的; 静态方法是被调用的时候才执行的. 二.静态方法注意事项 使用类的静态方法时,注意: a.在静态方法里只能直接调用同类中其他的静态成员(包括变量

java中的静态代码块、构造代码块、构造方法详解_java

运行下面这段代码,观察其结果: package com.test; public class HelloB extends HelloA { public HelloB() { } { System.out.println("I'm B class"); } static { System.out.println("static B"); } public static void main(String[] args) { new HelloB(); } } cla

Java中的static静态代码块

一.与静态方法的比较 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,静态方法在类加载的时候 就已经加载 可以用类名直接调用 比如main方法就必须是静态的 这是程序入口.两者的区别就是:静态代码块是自动执行的; 静态方法是被调用的时候才执行的.   二.静态方法注意事项 使用类的静态方法时,注意: a.在静态方法里只能直接调用同类中其他的静态成员(包括

java 中的静态方法和静态代码块分别装载到哪个区

问题描述 java中的静态方法和静态代码块分别装载到哪个区 解决方案 解决方案二: 解决方案三:楼主可看看楼上说的挺好学习了顶解决方案四:应该是栈里解决方案五:方法都是在方法区中,无论是不是静态的.方法表中有一个代码属性,代码属性存放方法代码.解决方案六:好,收了解决方案七:谢谢1楼的,学习了!

静态代码块,构造代码块,局部代码块演示

public class Test{         static int num;    static int numObj;//记录有多少个对象产生!    static{//静态代码块, 是用来给类进行初始化的!        //num = 10;        ++num;        num *=12;//没有进入静态代码块之前,num的初始化值是0        System.out.println(num);        //main(null);//静态代码块中可以调用ma

Java 25天基础-DAY 06-面向对象-静态代码块

/* 静态代码快 格式: static { 静态代码块中的执行语句. } 特点:随着类的加载而执行,只执行一次.优先于主函数执行. 用于给类进行初始化 / / class StaticCode { static { System.out.println("a"); } } */ class StaticCodeDemo { static { System.out.println("b"); } public static void main(String[] arg

Java 构造函数 静态代码块

问题描述 Java 构造函数 静态代码块 public class 静态 { public static void main(String[] args) { person p=new person(); p.show(); person p1=new person("xixi"); p1.show(); } } class person{ ** 这里显示"person"错误** private String name; { cry(); } { System.ou