菁's profile贫瘠的沙壤地PhotosBlogListsMore Tools Help

Blog


    19 July

    什么味儿……

    论坛上有个爷们……问了个很蛋疼的事儿:恋爱是什么滋味

    正赶上我最近也很蛋疼……就想了一下……

    感觉……这玩意儿,就跟冰葫儿一样……挺贱的,不值钱……

    虽然有好多种色……不过其实吃起来都一味儿……

    里边归了包堆就点糖和色素……

    所以吃的时候不能嘬……要不然吃到最后,就P味没有了……

    17 July

    相遇

    “童话中王子一定会和公主相遇吧?你知道为什么吗?”

    “不知道”

    “因为公主在等待,在他们一定会相遇的地方”

    ——《没有玫瑰的花店》

    这么看来姐姐们还真是狡猾啊- -!

    除了这部日剧,最近还看了部漫画《君吻》,看过之后同样觉得:姐姐是一种很狡猾的动物……

    看来相遇这种常常被当作起点的事……其实也不是那么容易的……

    06 July

    Java基于Socket的单进程实现

    有一阵很羡慕Win下的某些本地程序:因为他们可以实现单进程运行——不是设计模式里面说的单例,那个Java也可以,而由于Java程序每次启动都会启动新的虚拟机……所以单例和单进程是不同的概念。

    后来接触到了嵌入式DB……发现它可以自然的实现单例(机制貌似是文件锁定)……不过还是有些不足:他只能阻止第二个进程运行。但是不能向第一个进程传递消息(Win本地程序可以在启动第二个程序时,让第一个程序做最大化之类的动作)……

    网上查了一下,还有另一种方法:基于Socket的单进程实现。优点是可以传递消息给已经运行的进程。缺点是需要网络连接,对网络设置有依赖(比如防火墙设置、端口占用情况等)

    原理大概是这样:先向某个端口发消息,如果返回说已经有程序运行了。就执行某段代码,然后退出;如果没有返回就启动某端口的监听,等待消息。然后进入程序正常启动阶段。一旦有消息传过来,并且确认是同一个程序的另一个实例传过来的。就通知那个实例,已经有实例在运行了。然后运行另一段程序。

    具体的实现代码如下:

    /*SingleCases.java——单进程接口*/

    package turnip.gray.singlecases;

    public interface SingleCases {
        //运行程序
        void run();
        //指定程序标识:程序运行前首先会检查此标识。如果当前运行程序的标识,与某个已运行程序的标识相同。则激活已运行监听,并向已运行程序发送消息,使其激活其他程序启动监听
        void setAppe(Class<?> appe);
        //设置已有实例运行时的动作监听
        void setWhenAppIsRunning(WhenAppIsRunning whenAppIsRunning);
        //设置有其他实例尝试运行时的动作监听
        void setWhenOtherAppIsRunning(WhenOtherAppIsRunning whenOtherAppIsRunning);
    }

    /*SocketSingleCases.java——基于端口的单进程的实现*/

    package turnip.gray.singlecases;

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;

    public class SocketSingleCases implements SingleCases {

        private int port;
        private WhenAppIsRunning whenAppIsRunning;
        private WhenOtherAppIsRunning whenOtherAppIsRunning;
        private Class<?> appe;
        private ServerSocket ListenServerSocket;
        private ServerSocket requestServerSocket;
        public SocketSingleCases(){
            port=2048;
        }

        public WhenAppIsRunning getWhenAppIsRunning() {
            return whenAppIsRunning;
        }

        public void setWhenAppIsRunning(WhenAppIsRunning whenAppIsRunning) {
            this.whenAppIsRunning = whenAppIsRunning;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (isRunning()) {
                whenAppIsRunning.doThis();
            } else {
                try {
                    ListenServerSocket = new ServerSocket(port);
                    requestServerSocket = new ServerSocket(port + 1);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                runningFlag();
            }
        }

        private void runningFlag() {
            new Thread() {
                public void run() {
                    while (true) {
                        isOtherRunning(read(listen(requestServerSocket)));
                    }
                }
            }.start();
            new Thread() {
                public void run() {
                    while (true) {
                        write(listen(ListenServerSocket));
                    }
                }
            }.start();
        }

        private boolean isRunning() {
            boolean running = false;
            if (read(request(port))) {
                running = true;
                write(request(port + 1));
            }
            return running;
        }

        private Socket request(int port) {
            Socket socket = null;
            try {
                socket = new Socket("127.0.0.1", port);
                socket.setSoTimeout(200);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return socket;
        }

        private Socket listen(ServerSocket serverSocket) {
            Socket socket = null;
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return socket;
        }

        private void write(Socket socket) {
            OutputStream out = null;
            OutputStreamWriter outr = null;
            BufferedWriter bw = null;
            try {
                out = socket.getOutputStream();
                outr = new OutputStreamWriter(out);
                bw = new BufferedWriter(outr);
                bw.write(appe.getName());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    bw.close();
                    outr.close();
                    out.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        private boolean read(Socket socket) {
            boolean running = false;
            InputStream in = null;
            InputStreamReader inr = null;
            BufferedReader br = null;
            try {
                in = socket.getInputStream();
                inr = new InputStreamReader(in);
                br = new BufferedReader(inr);
                running = appe.getName().equals(br.readLine());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    br.close();
                    inr.close();
                    in.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            return running;
        }

        private void isOtherRunning(boolean running) {
            if (running) {
                whenOtherAppIsRunning.doThis();
            }
        }

        public WhenOtherAppIsRunning getWhenOtherAppIsRunning() {
            return whenOtherAppIsRunning;
        }

        public void setWhenOtherAppIsRunning(
                WhenOtherAppIsRunning whenOtherAppIsRunning) {
            this.whenOtherAppIsRunning = whenOtherAppIsRunning;
        }

        public Class<?> getAppe() {
            return appe;
        }

        public void setAppe(Class<?> appe) {
            this.appe = appe;
        }

    /*WhenAppIsRunning.java——简易的监听,当已经有程序运行时,执行doThis()*/

    package turnip.gray.singlecases;

    public interface WhenAppIsRunning {
        void doThis();

    }

    /*WhenOtherAppIsRunning .java——简易的监听,当其他程序尝试运行时,执行doThis*/

    package turnip.gray.singlecases;

    public interface WhenOtherAppIsRunning {
        void doThis();

    }

     

    写一个Demo看看效果吧:

    /*
    * DemoFrame.java
    *
    * Created on __DATE__, __TIME__
    */

    package turnip.gray.singlecases.demo;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import turnip.gray.singlecases.SingleCases;
    import turnip.gray.singlecases.WhenAppIsRunning;
    import turnip.gray.singlecases.WhenOtherAppIsRunning;

    /**
    *
    * @author  __USER__
    */
    public class DemoFrame extends javax.swing.JFrame {

        /**
         *
         */
        private static final long serialVersionUID = 1L;

        /** Creates new form DemoFrame */
        public DemoFrame() {
            initComponents();
        }

        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        //GEN-BEGIN:initComponents
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {

            setDefaultCloseOperation(3);

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
                    getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(layout.createParallelGroup(
                    javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400,
                    Short.MAX_VALUE));
            layout.setVerticalGroup(layout.createParallelGroup(
                    javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300,
                    Short.MAX_VALUE));

            pack();
        }// </editor-fold>
        //GEN-END:initComponents

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            SingleCases singlecases;
            final DemoFrame demoFrame;
            singlecases=new SocketSingleCases();
            demoFrame=new DemoFrame();
            singlecases.setAppe(demoFrame.getClass());
            singlecases.setWhenAppIsRunning(demoFrame.getWhenAppIsRunning());
            singlecases.setWhenOtherAppIsRunning(demoFrame.getOtherWhenAppIsRunning());
            singlecases.run();
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    demoFrame.setVisible(true);
                }
            });
        }
        public WhenAppIsRunning getWhenAppIsRunning(){
            WhenAppIsRunning whenAppIsRunning=new WhenAppIsRunning(){

                @Override
                public void doThis() {
                    // TODO Auto-generated method stub
                    System.exit(0);
                }
            };
            return whenAppIsRunning;
        }
        public WhenOtherAppIsRunning getOtherWhenAppIsRunning(){
            WhenOtherAppIsRunning whenOtherAppIsRunning=new WhenOtherAppIsRunning(){

                @Override
                public void doThis() {
                    // TODO Auto-generated method stub
                    int i=MAXIMIZED_BOTH;
                    int j=getExtendedState()^i;
                    setExtendedState(j);
                }
            };
            return whenOtherAppIsRunning;
        }

        //GEN-BEGIN:variables
        // Variables declaration - do not modify
        // End of variables declaration//GEN-END:variables

    }

    怎么样??是不是在尝试启动第二个实例的时候,原来的窗口被最大化了?

    03 July

    变味了……

    看了部日剧……《我的野蛮妈妈》……

    感觉变味了……越看越像韩剧……不光动作、表情夸张(电视剧外除了神经病,应该没人这么干)……而且怎么突然感觉连演员长得也那么像啊- -!

    印象中某可乐曾经改过一次口味……因为某人认为当时流行的是甜味的饮料……结果可耻的失败了……最后不得不改回来……

    怎么样都好,就是不要丢掉自己的东西……