<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    在路上

    路上有驚慌,路上有理想

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      28 Posts :: 1 Stories :: 10 Comments :: 0 Trackbacks

    2010年11月3日 #

    1.linux安裝字體
       以微軟雅黑為例,找到msyh.ttf ,copy至下面的文件夾
       usr/share/fonts/msyh
      執行命令:fc-cache -fv
      重啟jvm即可
    2.drawString 部分代碼
    private static BufferedImage drawString(int type, boolean isWhite,
                int width, int height, String price, Font font_money, Font font,
                Graphics2D g2d, Rectangle2D bounds, Rectangle2D bounds_money) {
             BufferedImage image;
             //透明背景
              image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);  
             g2d.dispose();  
             g2d = image.createGraphics();  
             //反鋸齒字體
             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
             if(!isWhite){
                 //非白字
                 g2d.setColor(new Color(236,0,137));  
             }else{
                 //白字
                 g2d.setColor(new Color(255,255,255));  
             }
             //字體居中
             double y = (height - bounds.getHeight()) / 2;      
             double ascent = -bounds.getY();      
             double baseY = y + ascent;      

             g2d.setStroke(new BasicStroke(1));  
             g2d.setFont(font_money);
             g2d.drawString(FONT_RMB_CHAR, -2, (int)baseY);  
             g2d.setFont(font);
             g2d.drawString(price, (int)bounds_money.getWidth()-4, (int)baseY);
             g2d.dispose();
             return image;
        }
    3.如果需要根據字符串的長度生成圖片的寬度,可以使用如下方法
     Rectangle2D bounds = font.getStringBounds(price, context);
     width = (int)(bounds.getWidth();

    4.批量生成,使用java自帶的線程池,并使用CompletionService,目的是在線程處理結束后得到生成成功的ProductId
          public boolean generateImagesBatch(){
              boolean flag=true;
              ExecutorService exec = Executors.newFixedThreadPool(8);
               CompletionService<CallBack> completionService=
                        new ExecutorCompletionService<CallBack>(exec);
              long startTime=System.currentTimeMillis();
                  String sql="select productId,price from prod";
                List<Map> skuList = this.cmsJdbcTemplate.queryForList(sql);
                for(Map map:skuList){
                    String prodId=((BigDecimal)map.get("productId")).toString();
                    double price=((BigDecimal)map.get("price")).doubleValue();
                    completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.ONE,false));               
                    completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.TWO,false));            }
                long endTime=System.currentTimeMillis()-startTime;
                log.info("query db time>>>>>>>>>>>>>>"+endTime/1000);
                
                Future<CallBack> future;
                int count=skuList.size()*6;
                log.info("generateImagesBatch count:"+count);
                try {
                    while(count>0){
                        future = completionService.take();
                        CallBack callBack = future.get();
                        if(null!=callBack){
                            count--; log.info("generateImagesBatch prod id:"+callBack.getSuccesMessage());                    }
                    }
                endTime=System.currentTimeMillis()-startTime;
                log.info("create images time>>>>>>>>>>>>>>"+endTime/1000);
                log.info("generateImagesBatch success!");
                flag=true;
                } catch (ExecutionException e) {
                    flag=false;
                    log.error("generateImagesBatch fail::ExecutionException::"+e.getMessage());
                } catch (InterruptedException e) {
                    flag=false;
                    log.error("generateImagesBatch fail::InterruptedException::"+e.getMessage());
                }finally{
                    exec.shutdown();
                }
                return flag;
          }
    posted @ 2012-04-18 11:35 阮步兵 閱讀(1860) | 評論 (0)編輯 收藏

    以下只是一些概念


    1.SemaphoreCountDownLatch
     
    Semaphore 可用于控制特定資源請求(線程/操作)數量
     
    CountDownLatch 在功能上類似于Semaphore。區別是,Semaphore允許一次一個線程的話,CountDownLatch可以允許多個線程在特定的時間一起執行。

    2.CAS操作
      根據英文直譯其實可以理解其含義,compare and set.

      CAS 操作包含三個操作數 —— 內存位置(V)、預期原值(A)和新值(B)。如果內存位置的值與預期原值相匹配,那么處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。CAS 認為位置 V 應該包含值 A;如果包含該值,則將 B 放到這個位置;否則,不要更改該位置,只告訴我這個位置現在的值即可通常將 CAS 用于同步的方式是從地址 V 讀取值 A,執行多步計算來獲得新值 B,然后使用 CAS 將 V 的值從 A 改為 B。如果 V 處的值尚未同時更改,則 CAS 操作成功。

    3.ABA問題

      因為在更改 V 之前,CAS 主要詢問“V 的值是否仍為 A”,所以在第一次讀取 V 以及對 V 執行 CAS 操作之前,如果將值從 A 改為 B,然后再改回 A,會使基于 CAS 的算法混亂。在這種情況下,CAS 操作會成功,但是在一些情況下,結果可能不是您所預期的。這類問題稱為 ABA 問題

    4.原子操作

       A與B兩個操作。從執行A的線程看,當其他線程執行B時,要么B全部執行完成,要么一點都不執行。這樣A與B互為原子操作。要保證數據狀態的一致性,要在單一的原子操作中更新所有相關聯的狀態。

    5.可見性
     
       在單線程環境下,讀寫操作都在一個線程內完成,不存在可見性問題。但是,當讀與寫操作不在同一個線程內時,就需要有可見性的要求——即可變的共享變量對所有線程都是可見的。

    6.重排序

        JVM實現中,線程內部維持順序化語義。如果程序的最終結果等同于它在嚴格的順序化環境下的結果,那么指令的執行順序就可能與代碼的順序不一致。這個過程通過叫做指令的重排序。比如Java存儲模型允許編譯器重排序操作指令,在寄存器中緩存數值,還允許CPU重排序,并在處理器的緩存中緩存數值。

       當然,在沒有同步的多線程情況下,編譯器,處理器,運行時安排操作的執行順序可能完全出人意料。

    7.內部鎖

      每個Java對象都可以隱士的扮演一個用于同步的鎖的角色。比如synchronized(object){},執行線程進入synchronized塊 之前自動獲得鎖。無論是正確執行或是拋出異常,最終都會釋放該鎖。內部鎖是一種互斥鎖(mutex)——至多只有一個線程可以擁有鎖。JDK中有該鎖的實 現。

    8.鎖與內存

       鎖不僅僅是關于同步與互斥,也是關于內存可見性的。為了保證所有線程都能訪問共享變量的最新值,讀和寫的線程必須使用公用的鎖進行同步。

    9.鎖與volatile

       加鎖可以保證可見性與原子性,volatile只能保證可見性。

    10.happen-before法則

      Java存儲模型有一個happens-before原則,就是如果動作B要看到動作A的執行結果(無論A/B是否在同一個線程里面執行),那么A/B就需要滿足happens-before關系。比如一個對象構造函數的結束happens-before與該對象的finalizer的開始


    參考:https://www.ibm.com/developerworks/cn/java/j-jtp11234/

         http://www.ibm.com/developerworks/cn/java/j-5things5.html

         http://www.tkk7.com/xylz/archive/2010/07/03/325168.html

        《Java 并發編程實踐》

    posted @ 2010-12-15 18:18 阮步兵 閱讀(1742) | 評論 (0)編輯 收藏

    BTrace是一個實時監控工具,使用了java agent jvm attach技術,可以在product的情況下實時監控線上程序的運行情況。另,有插件可與visualVM一起使用。
    不多說了,具體的可見:http://kenai.com/projects/btrace

    下面介紹幾個Helloworld示例:
    主要使用了btrace命令:btrace [pid] class

    pid可由jps命令快速查詢

    1.監控方法輸入參數:
     @OnMethod(
                    clazz="com.btrace.Person",
                    method="/set.*/"
                )
                public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
                    println(pcn);
                    println(pmn);
                    printArray(args);
                }

    執行btract命令
    后臺輸出:
    com.btrace.Person
    setId
    [1, ]……

    2.監控方法返回值
      @OnMethod(
                     clazz="com.btrace.Person",
                     method="/get.*/",
                     location=@Location(Kind.RETURN)
                   )  
         public static void defineclass(@Return String cl) {
               println(Strings.strcat("getValue ", cl));
               Threads.jstack();
           }
    執行btract命令
    后臺輸出:
    getValue gum
    com.btrace.TestThread.main(TestThread.java:23)

    3.監控jvm內存使用情況
      @OnTimer(4000)
        public static void printMem() {
            println("Heap:");
            println(heapUsage());
            println("Non-Heap:");
            println(nonHeapUsage());
        }
    執行btract命令
    后臺輸出:
    Heap:
    init = 268435456(262144K) used = 26175176(25561K) committed = 251658240(245760K)
     max = 492175360(480640K)
    Non-Heap:
    init = 12746752(12448K) used = 5892104(5754K) committed = 13598720(13280K) max =
     100663296(98304K)
    4.監控方法執行時間
       @TLS private static long startTime;
       
        @OnMethod(clazz="com.btrace.Person",method="setId")
        public static void onCall(){
            println("enter this method");
            startTime=timeMillis();
        }
       
        @OnMethod(clazz="com.btrace.Person",method="setId",location=@Location(Kind.RETURN))
        public static void onReturn(){
            println("method end!");
            println(strcat("Time taken ms",str(timeMillis()-startTime)));
        }
      后臺輸出:
       enter this method
       method end!
       Time taken ms0
    5.監控Thread start
     @OnMethod(
            clazz="java.lang.Thread",
            method="start"
        )
        public static void func() {
            println("about to start a thread!");
        }
    后臺輸出:about to start a thread!
    posted @ 2010-12-10 18:30 阮步兵 閱讀(3759) | 評論 (1)編輯 收藏

         摘要: 1.注意auto_increment mysql5.0在高并發下(每天近2億)插入單表數據出現了死鎖(偶現),查了下相關文檔,發現是因為采用了auto-increment的主鍵帶來的問題,造成Table級的死鎖。 原因:對于auto_increment字段,innodb會在內存里保存一個計數器用來記錄auto_increment的值,當插入一個新行數據時,就會用一個表鎖來鎖住這個計數器,所以會...  閱讀全文
    posted @ 2010-12-09 12:56 阮步兵 閱讀(1660) | 評論 (2)編輯 收藏

    一.限制設計——從結構上說,是利用封裝技術,保證某一時刻只有一個活動訪問某個對象。

    方式主要三類,方法限制、線程限制和對象內限制

    方法限制:

       1.方法內部限制:采用局部變量方式

       2.方法間傳遞限制:

             a.調用者copy:比如print(p) 可以改為print(new Point(p));

             b.接收者copy:Point p=new Point(p.x,p.y);

             c.標量參數:print(int x,int y);d.print(p.x,p.y);

    線程限制:

         1.最簡單的方法是將所有可變對象都放在一個線程內執行

                   public display(){

                             new Thread(){

                                      public void run(){//do something here}

                          }.start()

                    }

          2.線程私有成員變量

             最直接的辦法是利用現有類:ThreadLocal.

            當然你可以利用Thread.currentThread()自己實現一個類似功能的類,但Thread.currentThread有限制,就是對特定線程的一類。

            而ThreadLocal則擺脫了這樣的限制。而且在線程內對ThreadLocal私有變量的讀寫不需要同步。

    對象限制

           在前面兩種方法都不能做到對對象的限制訪問時,你就不得不使用鎖。但同時,也可以對對象內部及不同部分的訪問進行結構上的限制。

         1.適配器模式

          比如 class Point{

                     public double x;

                     public double y;

                     public synchronized double getX(){};

                    //……

          }

        采用對象限制的設計方式,會將synchronized 鎖移除到一個其他對象里,這樣就解脫了Point.

         like this

               class SychPoint {

                     private final Point point=new Point();

                    public synchronized double getX(){point.x}

             }

        class Point{

                     public double x;

                     public double y;

                     public double getX(){};

          }

        說白了就是采用適配器模式,改變了一下原來類的結構。java.util.Collection framework 里面就是使用這種策略組織起集合類的同步。

       2.子類化

           將鎖延遲到子類實現,這里將不再羅嗦。

    二.同步設計

         使用鎖的注意事項

           1.有些入口鎖在只有少數線程訪問的情況下,可以很好的工作,開銷并不大。但是當并發量變大,競爭加劇,開銷也變大,系統的性能會隨之下降。大多數線程會把大部分時間浪費在等待上。系統出現了延遲,限制了并發系統的優越性。

           2.使用太多的鎖,會增加系統負擔,以及不可料的情況發生,比如死鎖。

           3.只用一把鎖來保護一個功能的多個方面會導致資源競爭。

           4.長時間持有鎖,會帶來性能問題和異常處理的復雜。

           5.有時候加鎖并不一定能保證得到我們想要的結果。

        對付以上這些問題,沒有什么最佳策略,大都需要去權衡各個方面的利弊來進行設計。寫多線程的程序,前期的設計比后期維護更為重要。

        初期的設計原則,

            1.減少同步

                 a.用戶可以接受陳舊數據,可以拿掉同步,使用volatile

                 b.用戶在得到非法數據時,只要能得到提示就夠了,可以使用double-check方法。

                    在不同步時check一次,再在同步狀態在check一次。這么做的意義在于縮小鎖使用范圍,在第一次check不滿足的情況,跳出方法,那么鎖也就用不到了。

                 c.只對維護狀態部分加鎖:當對象的某個同步方法是比較耗時的操作,那么鎖持有的時間就越長,而僅僅是為了保持一個狀態是,可以采用openCall的方式,減少持有鎖時間。

                                  public sychronized void updateState(){}

                                  public void readFile(){

                                          updateState();//持有鎖

                                        file.read();

                                   }

                   如上,這種方式的前提是程序不需要同步一個方法中無狀態的部分。如果整個方法都需要鎖,那這種方式就不適用了.

                D.能使用同步塊,就不需同步整個方法。

         2.分解同步:

            分解類

                將鎖拆分到輔助類中

            分解鎖

               如果不愿分解類,可以設計分解鎖

                        private static Object lock1 = new Object();

                       private static Object  lock2 = new Object();

                      synchronize(lock1){}

                      synchronized(lock2){}

                  在jdk 5.0之后的并發包里,已有可重入鎖供使用。

              隔離成員變量

                  Person的age,income等屬性都需要同步處理,以保證并發修改時,可以設計一些同步的int,Double等類型(util.concurrent已提供類似的類),將鎖交給輔助類去處理。起到隔離作用.

     

    posted @ 2010-11-11 17:47 阮步兵 閱讀(1744) | 評論 (0)編輯 收藏

    Java 內存模型

    JVM系統中存在一個主內存(Main Memory),Java中所有變量都儲存在主存中,對于所有線程都是共享的。每條線程都有自己的工作內存(Working Memory),工作內存中保存的是主存中某些變量的拷貝,線程對所有變量的操作都是在工作內存中進行,線程之間無法相互直接訪問,變量傳遞均需要通過主存完成。

    模型的規則:

    1.原子性:保證程序得到成員變量(非局部變量)的值或者是初始值,又或者是某線程修改后的,絕對不是多個線程混亂修改后的。

    2.可見性(共享內存的數據):什么情況下,寫入成員變量的值對讀取該變量的值是可見的?

         A.寫操作釋放了同步鎖,讀操作獲得了同步鎖

               原理:釋放鎖的時候強制線程把所使用的工作內存中的值刷新到主存,獲得鎖的時候從主存重新裝載值。

               p.s.鎖只被同步塊和方法中的操作占有,但卻控制了執行該操作的線程的所有成員變量。

         B.如果一個成員變量為volatile,那么在寫線程做存儲操作前,寫入這個成員變量的數據會在主存中刷新,并對其他線程可見。讀線程每次使用這個成員變量前都要重新從主存讀數據。

         C.如果一個線程訪問一個對象的成員變量,讀到的值為初始值或者另一個線程修改后的值。

            p.s. 不要對引用未完全創建好的對象。

                   如果一個類可以被子類化,那么在構造函數里啟動一個線程是非常危險的

         D.當一個線程結束后,所有的寫入數據都會被刷新到主存。

              p.s.同一個線程的不同方法之間傳遞對象的引用,永遠不會有可見性問題

       存儲模型保證:如果上面的操作都會發生,那么一個線程對一個成員變量的更新最終對另一個線程是可見的。

    3.順序化(內存操作的順序):什么情況下,一個線程的操作可以是無序的?順序化的問題主要圍繞和讀寫有關的賦值語句的執行順序。

       如果采用同步機制,那不用多說,順序化可以保證。

       當沒有同步機制時,存儲模型所做的保證是難以相信的。在多線程環境下,存儲模型是難以保證一定正確的。

      只有當滿足下面的三個原則,順序化才得以保證。

       A.從線程執行方法的角度看,如果指令都是串行執行的,那么順序可以保證

       B.保證同步方法或塊的順序執行

       C.使用volatile定義成員變量

    線程執行過程中,存儲模型與鎖的關系:

    (1) 獲取對象的鎖

    (2) 清空工作內存數據, 從主存復制變量到當前工作內存, 即同步數據

    (3) 執行代碼,改變共享變量值

    (4) 將工作內存數據刷回主存

    (5) 釋放對象的鎖

    最后介紹一下volatile關鍵字

         volatile定義的成員變量可以保證可見性和順序化,但不保證原子性。比如count++。
         *比如把一個變量聲明為volatile,并不能保證這個變量引用的非volatile數據的可見性。比如volatile string[10](數組)

         正確使用volatile的前提條件

         a.對變量的寫操作不依賴于當前值

         b.不要和其他成員變量遵守不變約束。見*處的解釋

        volatile的應用

         a.狀態標志

            volatile boolean shutdownFlag;

           public void shutdown() { shutdownFlag= true; }
           public void doWork() {
           while (!shutdownFlag) {
            // do something
             }

         b.假設一個后臺線程可能會每隔幾秒讀取一次數據庫里的合同金額,并更新至 volatile 變量。然后,其他線程可以讀取這個變量,從而隨時能夠看到最新的金額。 比較廣泛應用在統計類的系統中。

    參考文檔:

    http://www.cs.umd.edu/~pugh/java/memoryModel/

    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

    《Java并發編程:設計原則與模式》

    posted @ 2010-11-03 17:56 阮步兵 閱讀(1455) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 免费人成网站在线高清| 欧美男同gv免费网站观看 | 国产亚洲精品成人AA片新蒲金| 欧美激情综合亚洲一二区| 男人的好看免费观看在线视频| 亚洲国产精品免费观看 | 99久久免费国产精品热| 亚洲人午夜射精精品日韩| 中文字幕无线码中文字幕免费 | 亚洲精品综合一二三区在线| 精品97国产免费人成视频 | 亚洲图片校园春色| 91免费精品国自产拍在线不卡| 亚洲va在线va天堂va手机| 午夜视频在线观看免费完整版| 亚洲精品V天堂中文字幕| 亚洲国产成人久久一区久久| 国产精品美女久久久免费| 亚洲精品国产美女久久久| 日韩在线永久免费播放| 亚洲伦理中文字幕| 国产公开免费人成视频| 国产黄色片免费看| 亚洲自偷自拍另类12p| 在线成人a毛片免费播放| 猫咪免费人成在线网站 | 中文字幕亚洲一区| 19禁啪啪无遮挡免费网站| 亚洲熟妇成人精品一区| 亚洲人成无码网WWW| 日韩插啊免费视频在线观看 | 在线精品免费视频无码的| 一级做α爱过程免费视频| 亚洲人成电影在线天堂| 成人无遮挡毛片免费看| 一个人晚上在线观看的免费视频| 亚洲视频一区调教| 免费在线观看你懂的| 最好看的中文字幕2019免费| 精品亚洲成a人在线观看| 亚洲av不卡一区二区三区 |