高并发下System.currentTimeMillis()需慎用

前几天做了个为图片添加水印 ,实现自动盖章的功能,在正常试运行几天后,用户突然反馈有些文件下载不下来。通过查看系统日志发现,在盖章的代码里,出现了文件丢失的错误。经过各种模拟排查与bug重现,发现是在自动生成签字章图片的时候用了System.currentTimeMillis()来命名。一般来说,这样的命名方式不会产生冲突。但在超高并发的情况下,会出现在极短的时间内同时生成一份文件,并同时进行相关操作的情况。而且由于缓存的图片文件也以该方式命名,导致在执行完某段程序后,删除缓存文件可能存在误删同名文件的错误,进而导致文件寻找失败。之后改用System.nanoTime()来命名文件后便不再出现该错误。

附上盖章代码

导入工具类:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.AttributedString;

import javax.imageio.ImageIO;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
/**
	 *盖章,
	 * @param inputfile
	 * @param outputfile
	 * @param username
	 * @throws DocumentException
	 * @throws IOException
	 */
	public static void setWatermarkForBill(String inputfile,String outputfile,String username)
			throws DocumentException, IOException {
		PdfReader reader = new PdfReader(inputfile);
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputfile)));
		PdfStamper stamper = new PdfStamper(reader, bos);
		String zhang1=null;
		String zhang2=null;
		try
		{
			int total = reader.getNumberOfPages() + 1;
			PdfContentByte content;
			PdfGState gs = new PdfGState();
			//第一章盖章图片
			zhang1=generateStyle2Sign(username);	
			//第二张盖章图片
			zhang2=generateStyle3Sign();
			for (int i = 1; i < total; i++) {
				content = stamper.getOverContent(i);// 在内容上方加水印
				gs.setFillOpacity(0.7f);
				content.beginText();
							
				Image image = Image.getInstance(zhang1);				
				image.setAbsolutePosition(415, 6); 
				image.scaleToFit(130,70);
				content.addImage(image);
				
				
				image = Image.getInstance(zhang2);
				image.setAbsolutePosition(250,50); 
				image.scaleToFit(130,70);
				content.addImage(image);
				
				content.endText();
			}
		}finally
		{
			try {
				stamper.close();
				reader.close();
				bos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(zhang1!=null)
			{
				File file=new File(zhang1);
				if(file.exists())
				{
					file.delete();
				}
			}
			if(zhang2!=null)
			{
				File file=new File(zhang2);
				if(file.exists())
				{
					file.delete();
				}
			}
			
		}
	}
/**
	 * 生成签章
	 * @param username
	 * @return
	 * @throws IOException
	 */
	public static String generateStyle2Sign(String username) throws IOException {
		int imageWidth = 400;
		int imageHeight = 215;

		BufferedImage image = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = (Graphics2D) image.getGraphics();
		g2d.setColor(Color.WHITE);
		g2d.fillRect(0, 0, imageWidth, imageHeight);

		// ---------- 增加下面的代码使得背景透明 -----------------
		 image =
		 g2d.getDeviceConfiguration().createCompatibleImage(imageWidth,
		 imageHeight, Transparency.TRANSLUCENT);
		 g2d.dispose();
		 g2d = image.createGraphics();
		// ---------- 背景透明代码结束 -----------------

		g2d.setColor(new Color(220, 240, 240));
		g2d.setStroke(new BasicStroke(10.0f));
		// 画横线
		g2d.setColor(Color.red);

		g2d.drawLine(1, 1, imageWidth - 1, 1);
		g2d.drawLine(1, imageHeight - 1, imageWidth - 1, imageHeight - 1);
		// 画竖线
		g2d.setColor(Color.red);
		g2d.drawLine(1, 1, 1, imageHeight - 1);
		g2d.drawLine(imageWidth - 1, 1, imageWidth - 1, imageHeight - 1);

		// 设置字体
		Font font = new Font("宋体", Font.BOLD, 60);
		g2d.setFont(font);
		// 写入内容
		g2d.setColor(Color.red);		
	    g2d.drawString("xx 文 件", 20, 80);
	    
	    font = new Font("宋体", Font.BOLD, 40);
	    String line="批准人:           ";
	    AttributedString as = new AttributedString(line);
	    as.addAttribute(TextAttribute.FONT, font);
	    as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 3,line.length());
	    g2d.drawString(as.getIterator(), 20, 190);
	    
	    font = new Font("宋体", Font.BOLD, 48);
	    g2d.setFont(font);
	    g2d.setColor(Color.blue);
	    g2d.drawString(username, 160, 188);
//		String path = imagePath+File.separator+System.currentTimeMillis()+".png";
	    String path = imagePath+File.separator+System.nanoTime()+".png";//修改命名方式,防止同一时间操作导致图纸重名bug
		ImageIO.write(image, "png", new File(path));
		return path;
	}

 

你可能感兴趣的:(Java编程)