洛神賦

          子虛烏有

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

          2010年11月8日 #

          知識點一:分類
                   IO
          中按照數據流的方向不同可以分為輸入流和輸出流(以程序的角度來考慮)

                   按照數據單位的不同可以分為字節流和字符流。

                   按照功能的不同可以分為節點流和處理流。


          知識點二: 四大等級結構

            java語言的i/o庫提供了四大等級結構:InputStream,OutputStream,Reader,Writer四個系列的類。InputStream和OutputStream處理8位字節流數據, Reader和Writer處理16位的字符流數據。InputStream和Reader處理輸入, OutputStream和Writer處理輸出。大家一定要到J2SE文檔中看看這四大等級結構的類繼承體系。

            除了這四大系列類,i/o庫還提供了少數的輔助類,其中比較重要的是InputStreamReader和OutputStreamWriter。InputStreamReader把InputStream適配為Reader, OutputStreamWriter把OutputStream適配為Writer;這樣就架起了字節流處理類和字符流處理類間的橋梁。

            您使用I/O庫時,只要按以上的規則,到相應的類體系中尋找您需要的類即可

          下面我就會對I/O 進行不定期更新:

          1 FileOutputStream 文件字節流

          Public class FileInputStream extends InputStream

            {

            /* File Descriptor - handle to the open file */

            private FileDescriptor fd;

            public FileInputStream(FileDescriptor fdObj)

            {

            SecurityManager security = System.getSecurityManager();

            if (fdObj == null) {

            throw new NullPointerException();

            }

            if (security != null) {

            security.checkRead(fdObj);

            }

            fd = fdObj;

            }

            //其他代碼

            }

            可見,FileInputStream繼承了InputStream,組合了FileDescriptor,采用的是對象Adapter模式。我們學習i/o庫時,主要應該掌握這四個對象Adapter模式的適配源: ByteArrayInputStream的適配源是Byte數組, FileInputStream的適配源是File對象, PipedInputStream的適配源是PipedOutputStream對象, StringBufferInputStream的適配源是String對象



          posted @ 2010-11-13 11:52 洛神賦 閱讀(309) | 評論 (0)編輯 收藏


          線程間通信:一個線程向數據存儲空間添加數據(唐老鴨),另一個線程從數據存儲空間取出數據(米琪)。

          程序有兩種以外需要考慮:

          1、      假設唐老鴨線程剛向數據存儲空間添加了一輛車的名字。還沒有加入這輛車的顏色,CPU就切換到了米琪線程,唐老鴨線程將把這輛車的名字和上輛車的顏色聯系到了一起。

          2 、唐老鴨了若干次的數據。米琪才開始取數據,或者是,米琪取完了一個數據后,還沒等到唐老鴨放入新的數據,又重復取出已取過的數據。

          可能出現的問題:

          1唐老鴨米琪快時,米琪會漏掉一些數據沒有取到。

          2、      米琪唐老鴨快時,米琪取相同的數據。

          多個線程共享同一資源的時候,必須進行同步,采用同步方法,解決第一個問題。

          線程的等待和喚醒機制:

          wait():告訴當前線程放棄監視器并進入睡眠狀態,直到其他線程進入同一監視器并調用notify為止。

          notify():喚醒同一對象監視器中調用wait的第一個線程。

          程序中采用線程的等待和喚醒機制,當發現米琪沒有取走內容時,唐老鴨應該等待,當米琪把內容取走之后,唐老鴨才可以放。這樣解決了第二個問題。


          代碼如下:


          package Killva.IOchaper4.o3;


          class Animal{
           private String name ="唐老鴨";
           private String  sex= "公";
           private boolean flag=false;
           
           public synchronized void set(String name, String sex){//生產者
            //如果flag的值不是true則要等待
            
            if(!flag){
             //等待
             try{
              wait();
             }catch(Exception e){}
             
            }
            //如果向下繼續執行了,則表示可以設置, flag =true
            this.name=name;
            this.sex=sex;
            //修改設置的標志
            flag = false;
            //喚醒其他線程
            notify();
           }
           //設置一個輸出的方法
           public synchronized void get(){
            //如果flag的值為true的時候,表示要等待
            if(flag){
             try{
              wait();
              
             }catch(Exception e){}
             
            }
            //如果向下執行了,就表示允許
            System.out.println(this.name+"-->"+this.sex);
            //改變標簽
            flag =true;
            notify();
           }
          }

          class Pro implements Runnable{
           Animal per =null;
           public Pro(Animal p){
            this.per=p;
            
           }
           public void run() {
            int i =0;
            
            while (true){
             
             if(i==0){
              per.set("米琪", "母");
              i=1;
              
             }else{
              per.set("唐老鴨", "公");
              i=0;
             }
            }
           }
          }

          class Cus implements Runnable{
           Animal per =null;
           public Cus(Animal p){
            this.per=p;
           }
           public void run() {
            while(true){
               per.get();
            }
           }
          }


          public class Demo01 {
           //主方法
           public static void main(String[] args){
            Animal per =new Animal();
            Pro p =new Pro(per);
            Cus c =new Cus(per);
            
            new Thread(p).start();
            new Thread(c).start();
            
           }

          }

          運行結果:




          感謝閱讀 !!!歡迎交流!!!    QQ:237333696
          posted @ 2010-11-13 11:12 洛神賦 閱讀(923) | 評論 (0)編輯 收藏

                   所謂socket通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。Socket和ServerSocket類庫位于java.net包中。ServerSocket用于服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對于一個網絡連接來說,套接字是平等的,并沒有差別,不因為在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
          下面是我忍為比較重要的API:
                  1、. Accept方法用于產生"阻塞",直到接受到一個連接,并且返回一個客戶端的Socket對象實例。"阻塞"是一個術語,它使程序運行暫時"停留"在這個地方,直到一個會話產生,然后程序繼續;通常"阻塞"是由循環產生的。

            2、. getInputStream方法獲得網絡連接輸入,同時返回一個InputStream對象實例,。

            3、. getOutputStream方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例。

            注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。

            寫代碼時一般先寫server端.
          //Server

          package Killva.NetWorkchaper1.o3;

          import java.io.DataOutputStream;
          import java.io.IOException;
          import java.net.ServerSocket;
          import java.net.Socket;

          public class TestTCPServer {
           public static void main(String args[])throws IOException{
            ServerSocket ss =new ServerSocket(9999);
            while(true){
             System.out.println("--------服務端已近啟動------------");
                Socket s =ss.accept();
               
                DataOutputStream dos =new DataOutputStream(s.getOutputStream());
               
                System.out.println("客戶端["+s.getInetAddress().getHostAddress()+
                               "  :"+s.getPort()+
                               "]已近鏈接!");
                dos.writeUTF("服務器端寫入客戶端的數據:客戶端("+
                         s.getInetAddress().getHostAddress()+
                          "  :"+s.getPort()+
                                  "]已經鏈接上服務器端["+
                                  s.getLocalAddress().getHostName()+
                                  ":"+s.getLocalPort()+
                                  "]!");
               
                dos.flush();
                dos.close();
                s.close();
               
               
            }
           }
           

          }



          Client端

          package Killva.NetWorkchaper1.o3;

          import java.io.DataInputStream;
          import java.io.IOException;
          import java.net.Socket;


          public class TestTCPCLient {
           public static void main(String[] args) throws IOException{
            System.out.println("-------------client端-----------");
            for(long i=0;i<10;i++){
             Socket s =new Socket("192.168.1.*",9999);//IP是用你所在的局域網來測試
             
             DataInputStream dis = new DataInputStream(s.getInputStream());
             System.out.println(""+dis.readUTF());
             dis.close();
             s.close();
            }
           }
          }


          運行結果真確時服務器端和客戶端能連接

          感謝閱讀!!!!



          posted @ 2010-11-13 09:51 洛神賦 閱讀(480) | 評論 (0)編輯 收藏

          創建線程有兩種方法:繼承Thread類和實現Runnable接口。
           
          方法一:繼承 Thread 類,覆蓋方法 run(),我們在創建的 Thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。

          a.每個線程都是通過某個特定Thread對象所對應的方法run()l來完成其操作的,方法run()成為線程體。

          b.如果想要啟動多線程,則肯定調用start()方法,start方法可以調用被子類覆寫過的run方法

          c.不過這種這種實現方式會受到單繼承的局限

          下面是一個例子:
          public class MyThread extends Thread {
          int count= 1, number;
          public MyThread(int num) {
          number = num;
          System.out.println("創建線程 " + number);
          }
          public void run() {
          while(true) {
          System.out.println("線程 " + number + ":計數 " + count);
          if(++count== 6) return;
          }
          }
          public static void main(String args[]) {
          for(int i = 0; i < 5; i++) new MyThread(i+1).start();
          }
          }
           
          方法二:實現 Runnable 接口
            Runnable 接口只有一個方法 run(),我們聲明自己的類實現 Runnable 接口并提供這一方法,將我們的線程代碼寫入其中,就完成了這一部分的任務。
          但是 Runnable 接口并沒有任何對線程的支持,我們還必須創建 Thread 類的實例,這一點通過 Thread 類的構造函數public Thread(Runnable target);來實現。

          該實現方式有以下好處:

               適合多個相干同程序代碼的線程去處理同一資源的情況。

               可以避免由于Java單繼承特性帶來的局限。

               有利于程序的健壯性,代碼能夠被多個線程共享。

          下面是一個例子:
          public class MyThread implements Runnable {
          int count= 1, number;
          public MyThread(int num) {
          number = num;
          System.out.println("創建線程 " + number);
          }
          public void run() {
          while(true) {
          System.out.println("線程 " + number + ":計數 " + count);
          if(++count== 6) return;
          } 
          }
          public static void main(String args[]) {
          for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();
          }
          }
            兩種方法各有千秋,可以靈活運用。





          posted @ 2010-11-08 11:56 洛神賦 閱讀(266) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 蒙城县| 盐亭县| 丹巴县| 石嘴山市| 清镇市| 龙口市| 内江市| 宁波市| 宜黄县| 建水县| 屯门区| 武山县| 长春市| 通河县| 陈巴尔虎旗| 西乡县| 清水县| 美姑县| 会东县| 鹤峰县| 盱眙县| 元江| 札达县| 南漳县| 南平市| 太白县| 铜陵市| 麦盖提县| 石门县| 庆阳市| 张家港市| 泸定县| 西藏| 镶黄旗| 新建县| 新密市| 浪卡子县| 邢台县| 徐水县| 阿荣旗| 石台县|