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

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

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

    隨筆 - 18  文章 - 96  trackbacks - 0
    <2007年12月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345


    常用鏈接

    留言簿(4)

    隨筆檔案

    相冊

    我的兄弟們

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

         摘要: 很久沒有回來這里寫技術BLOG了,這里的氛圍還行,大家都對一個問題積極的思考(至少之前這里給我的感覺是這樣的),2年里面自己也忙著做些事情,沒有寫,最近有空也就寫寫,偶爾會去oschine.net看看新聞,然后就在那里看到了一個人提出的問題很有意思,就是怎么表達式求解,例如(1 + 2) / 3 - 1 * 2 + 5 / (3 + 2)這樣的字符串輸入,怎么樣解析之后輸出結果。說來也好笑,對于我...  閱讀全文
    posted @ 2011-11-09 10:36 ruislan 閱讀(1762) | 評論 (6)編輯 收藏
         摘要: 很久沒來了,不是一位朋友給我發郵件問我關于swing的問題,才想起,然后翻看了之前的代碼,發現當年還實現了一個Vista風格的按鈕沒有放出來,現在補上,也許現在人們的swing水平對我這代碼不屑一顧,不過還是依然拋磚引玉,給未知的人們一個啟發。還是老慣例,上效果圖: 正常情況下:(和vista一樣具有焦點的按鈕的顏色漸深漸淺的循環變化) 鼠標在區域內時: 鼠標按下去: 然后是代...  閱讀全文
    posted @ 2009-09-12 12:54 ruislan 閱讀(2487) | 評論 (3)編輯 收藏
    認為自己是達人的就不用看了。只是一點小技巧,不敢班門弄斧,做個總結,為那些還不知道的解解惑,隨便告訴大家我還活著。

    最近客戶提了個小改動,客戶網站上圖片存放的目錄需要改動一下。例如在網上訪問是m.tkk7.com/images/*.*,在服務器上的目錄是D:/<webroot>/images/*.*,客戶想把這個images目錄下的資源全部移動到E:/data/里面去,但是在網上m.tkk7.com/images/*.*還是同樣可以訪問得到,我剛開始犯了形式主義的錯誤,老是想用程序解決,一會filter,一會servlet/action,后來我配置程序的時候突然看到了server.xml,于是我想到了選擇用映射的方式。正好,server.xml中的<Context>就是做這個事情的。于是乎我們在<Host></Host>中增加了一個<Context docBase="E:/data/images" path="/images">,OK,重啟之后,所有檢索m.tkk7.com/images路徑下的資源實際上都由E:/data/images下的資源提供了。

    posted @ 2008-02-15 16:41 ruislan 閱讀(1272) | 評論 (3)編輯 收藏
    在寫多線程程序的時候,你就像個經理,手下有那么或多或少的職員,你負責協調職員之間的工作,如果你稍不留神,職員之間就陷入了相互等待的尷尬狀態。還好,大多數時候多線程都還在我們掌控之內,即便是遇到這樣的deadlock情況,我們也能夠去修正,但是有的時候生活就是那么不盡人意,特別是NIO這種你不能掌控的時候,且看下面的代碼:

    /**
     * @(#)DeadLock.java  v0.1.0  2007-12-13
     
    */
    package ruislan.rswing.test;

    import java.net.InetSocketAddress;
    import java.nio.channels.ClosedChannelException;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.concurrent.Executors;

    /**
     * NIO DeadLock
     * 
     * 
    @author ruislan <a href="mailto:z17520@126.com"/>
     * 
    @version 0.1.0
     
    */
    public class DeadLock {
        
    public static void main(String[] args) throws Exception {
            Service service 
    = new Service();
            Executors.newSingleThreadExecutor().execute(service);

            SocketChannel channel 
    = SocketChannel.open();
            channel.configureBlocking(
    false);
            channel.connect(
    new InetSocketAddress("http://m.tkk7.com"80));
            service.addChannel(channel);
        }

        
    static class Service implements Runnable {
            Selector selector;

            
    public Service() {
            }

            
    public void run() {
                
    try {
                    selector 
    = Selector.open();
                    
    while (true) {
                        selector.select();
                        System.out.println(selector.selectedKeys().size());
                    }
                } 
    catch (Exception e) {
                }
            }

            
    public void addChannel(SocketChannel channel) {
                
    try {
                    channel.register(selector, SelectionKey.OP_CONNECT
                            
    | SelectionKey.OP_READ);
                    System.out.println(
    "can reach here?when pigs fly!");
                } 
    catch (ClosedChannelException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    乍看之下,我們的代碼沒有問題,但是運行之后你會發現,這句System.out.println("can reach here?when pigs fly!");永遠無法執行,也就是說register()方法被阻塞了!Oh god bless,讓我們看看JavaDoc是怎么說的:

    ...
    可在任意時間調用此方法。如果調用此方法的同時正在進行另一個此方法或 configureBlocking 方法的調用,則在另一個操作完成前將首先阻塞該調用。然后此方法將在選擇器的鍵集上實現同步,因此如果調用此方法時并發地調用了涉及同一選擇器的另一個注冊或選擇操作,則可能阻塞此方法的調用。
    ...

    看這句“可在任意時間調用此方法。”,也就是說我們調用的時間沒有任何限制,而阻塞的情況只會出現在“如果調用此方法的同時正在進行另一個此方法或 configureBlocking 方法的調用”的情況下,即便是阻塞了,我相信“正在進行另一個此方法或configureBlocking”也不會花掉太多的時間,況且這里沒有上面這樣的情況出現。那register()是被誰擋住了?或者是BUG?

    我們來分析一下程序,程序有兩個線程主線程和Service線程,主線程啟動后啟動了Service線程,Service線程啟動Selector然后Service線程陷入select()的阻塞中,同時,主線程調用Service的addChannel()方法來添加一個SocketChannel,嗯,兩個線程之間唯一的聯系就是selector,看來要從selector尋找線索,很可惜,selector的實現沒有源代碼可查,不過可以肯定是channel的register()會調用selector的register(),雖然此時持有selector的Service線程被select()方法所阻塞,但是并不影響其他線程對其操作吧?那么,剩下的解釋就是Selector的select()方法和register()方法公用了一個鎖,select()方法阻塞住了,所以register()拿不到這個鎖了,那么這樣一來我們就只能保證讓select()或者register()不能同時調用或者register()調用的時候select()不持有這個鎖,也就是說我們要用Service線程自己來執行addChannel()方法,所以改進如下:

    /**
     * @(#)DeadLock.java  v0.1.0  2007-12-13
     
    */
    package ruislan.rswing.test;

    import java.net.InetSocketAddress;
    import java.nio.channels.ClosedChannelException;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.Queue;
    import java.util.concurrent.LinkedBlockingQueue;

    /**
     * NIO DeadLock
     * 
     * 
    @author ruislan <a href="mailto:z17520@126.com"/>
     * 
    @version 0.1.0
     
    */
    public class DeadLock {
        
    public static void main(String[] args) {
            Service service 
    = new Service();
            
    new Thread(service).start();
            
    for (int i = 0; i < 5; i++) {
                
    new Thread(new ChannelAdder(service)).start();
            }
        }

        
    static class ChannelAdder implements Runnable {
            
    private Service service;

            
    public ChannelAdder(Service service) {
                
    this.service = service;
            }

            @Override
            
    public void run() {
                
    try {
                    SocketChannel channel 
    = SocketChannel.open();
                    channel.configureBlocking(
    false);
                    channel.connect(
    new InetSocketAddress(
                            
    "http://m.tkk7.com"80));
                    service.addChannel(channel);
                } 
    catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        
    static class Service implements Runnable {
            
    private Selector selector;
            
    private Queue<SocketChannel> pendingRegisters;

            
    public Service() {
                pendingRegisters 
    = new LinkedBlockingQueue<SocketChannel>();
            }

            
    public void run() {
                
    try {
                    selector 
    = Selector.open();
                    
    while (true) {
                        selector.select();
                        System.out.println(selector.selectedKeys().size());
                        handlePendingRegisters();
                    }
                } 
    catch (Exception e) {
                }
            }

            
    public void handlePendingRegisters() {
                
    while (!pendingRegisters.isEmpty()) {
                    SocketChannel channel 
    = pendingRegisters.poll();
                    
    try {
                        channel.register(selector, SelectionKey.OP_CONNECT);
                        System.out.println(
    "can reach here?yeah!");
                    } 
    catch (ClosedChannelException e) {
                        e.printStackTrace();
                    }
                }
            }

            
    public void addChannel(SocketChannel channel) {
                pendingRegisters.offer(channel);
                selector.wakeup();
            }
        }
    }


    新的代碼,我們在Service的線程提供了一個待處理Channel隊列,然后在添加一個SocketChannel到隊列中時喚醒這個selector,取消阻塞,然后在Service的循環中處理這個pendingChannel,這樣就避免這個Deadlock的發生了。當然我們亦可以在那個代碼上將select的超時時間設置非常的短,然后讓兩個線程去競爭,這樣做有太多的不可控性,不推薦了。

    posted @ 2007-12-13 18:31 ruislan 閱讀(1350) | 評論 (3)編輯 收藏
    主站蜘蛛池模板: 少妇人妻偷人精品免费视频| 无人视频免费观看免费视频 | 亚洲最大中文字幕无码网站| 99xxoo视频在线永久免费观看| 久久久久亚洲AV无码专区首| 成全视频高清免费观看电视剧| 亚洲国产精品成人精品无码区| 国产激情免费视频在线观看| 久久精品国产亚洲AV香蕉| 99精品视频在线观看免费播放| 亚洲日韩在线视频| 大地资源二在线观看免费高清| 亚洲综合久久精品无码色欲| 四虎免费永久在线播放| sss在线观看免费高清| 国产亚洲福利精品一区| 久草视频在线免费| 亚洲av日韩av永久无码电影| 亚洲av日韩av欧v在线天堂| a级特黄毛片免费观看| 亚洲黄色免费电影| 国产美女精品久久久久久久免费 | 亚洲深深色噜噜狠狠网站| 日韩成人免费aa在线看| 七次郎成人免费线路视频| 久久久久噜噜噜亚洲熟女综合| 久久久久久久久久国产精品免费| 亚洲码一区二区三区| 国产一区二区三区免费视频| 大地资源在线资源免费观看| 亚洲国产精品综合一区在线| jjzz亚洲亚洲女人| 午夜精品一区二区三区免费视频| 亚洲熟妇成人精品一区| 国产精品亚洲视频| 麻豆国产精品免费视频| 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲乱码精品久久久久..| h在线观看视频免费网站| 小说专区亚洲春色校园| 亚洲AV乱码久久精品蜜桃 |