线程周知识

1.15

回顾:

精华笔记:

       技能点:线程、socket聊天室、服务端;

       一、多线程并发安全

           1. 相关概念:

                      a.线程: 单一顺序的控制流;

                      b.多线程:并发执行的单一顺序控制流;

                      c.并发:微观上走走停停,宏观上一起运行的现象;

           2、线程

                     a.分类:

                            用户线程:

                            守护线程:普通线程调用setDaemon(true)方法得到的线程;

                     b.线程的两种创建方式;

                       *继承thread重写run方法:     优点:结构简单;

                                                                     缺点:不能再继承其它类、不利于线程的重用;

                       * 实现Runnable接口   优点:a可以多实现,没有继承冲突; b.  便于线程的重用;                                                            缺点:创建稍复杂;

                      c.线程信息的获取  ;

                               线程优先级:线程只能被动的被分配时间片并发运行,而线程调度器负责均                           匀的将时间片分配给线程;

                               睡眠阻塞: static void sleep(long ms)

                                                  线程进入阻塞状态,超时后等待,再次获取时间片并发运行;

                      d.线程有关的方法:

                                   启动:        static Thread currentThread():

                                   属性:        long getId():

                                   线程信息: void setPriority(int priority):

                                   判断:           boolean isDaemon():

                   3.多线程并发安全:并发运行时,由于切换时机的不一致,导致执行顺序出现的混乱;

                            synchronized关键字、

                            互斥锁;  synchronized锁定多个代码段的同时,锁对象是同一个,那么这些代                         码段是互斥的;

          

Foo foo=new Foo();



Class Coo{
   public synchronized void methodA(){
       
     }
   public synchronized void methodB(){

     }
  }
Foo对象的两个方法,一个类只能同时对应一个对象,故互斥锁是同步有序的;
、、互斥和同步还是不同的。

             二、synchronized关键字;

                             
                             两种方式

                                   同步方法:被synchronized修饰的方法;

                                   同步块:    a.定义:锁定排队的代码段;

                                                      b.语法:   synchronized(同步监视器对象){

                                                            多线程同步执行的代码段                                 };

                                                      c.(同步监视器对象即上锁的对象):

                           ------------修饰类、实例方法、静态方法、代码块;

                    锁对象为实例方法时,锁对象是this;当new 一个对象,一个类只对应一个对象,故此时是同步有顺序的;//而 new两个对象时,此时相互不影响this不同,可以同时进行; 

实例方法
new一个对象,同步;
Shop shop=new Shop();

Class Coo{
   public  synchronized void buy(){
                         
      }
}
------------
new两个对象,同时
Shop shop1=new Shop();
Shop shop2=new Shop();

Class Coo{
    public synchronized void buy(){

         }
}



                    锁对象为静态时,代码段同步执行;

                    当synchronized修饰静态方法时,此时锁对象为类对象;当synchronized在同步块中         时,锁对象为类名.class;

含静态方法的同步方法
Class Boo{
public synchronized static void dosome(){
              }     
         }

含静态方法的同步块
Class Boo{
public static void dosome(){
         synchronized(Boo.class){
                 }
         }
}

         

                                                      d.要求:同步监视器对象是同一个;

   三、聊天室;

          a. 目的:建立服务器端与客户端并进行连接,实现发消息等功能;

           b.思路:

                   客户端:1、建立连接;2、第一次通讯 ;3、循环发消息;

            4、多客户端链接(利用多线程)

                    服务端:5、服务端发消息;  6、服务器转发所有消息;

           c.步骤(语句、方法、对象):

                   1.建立连接;

                  客户端:   建Client类,声明socket对象,写无参构造方法(实例化socket)、开始工作start方法(包含了getOutputStream方法);

                       服务端: 建Server类,声明serversocket对象,写无参构造方法(实例化8088端口、                     getInputStream()方法)、开始工作start的方法(包含了socket accept阻塞方法);

                 

客户端
public Class Client{
     private Socket socket;
     public Client(){
         try{       
             System.out.println("正在链接服务端");
             socket=new Socket("localhost",8088);
             System.out.println("成功链接服务端");
        } catch (IOException e){
            e.printStackTrace();
              }
          }


 public void start(){
             OutputStream out=socket.getOutputStream();
             OutputStreamWriter osw=new OutputStreamWriter(out);
             bufferedwriter bw=new bufferedwriter(osw);
             printWriter pw=new printWriter(bw);
               

       }

 public static void main(String[] args){
         Client client=new Client();
         client.start();                    
      }
}

---------------------------------------------------------------------
服务端:

Class Server{
        private ServerSocket serverSocket; 
        public Server(){
             try{
              System.out.println("正在启动服务端");
              serverSocket=new ServerSocket(8088);
              System.out.println("服务端启动完毕");
                 }catch(IOException e){
                   e.printStackTrace(); 
                 }
       
         public void start(){
            try{
              System.out.println("链接客户端");
              Socket socket=serverSocket.accept();
              System.out.println("与一个客户端连接了");
                      }catch(IOException e){     
                        e.printStackTrace();
                   }
        
         public static void main(String[] args){
               Server server=new Server();
               server.start();
               }
          }

            2、第一次通讯(发送一行字符串)

                  客户端:在start方法添加getOutputStream方法,扫描定义字符串、if分支结构判断并输出;通讯完毕,添加socket.close()方法;----try-catch捕获异常

                  服务端:在start方法添加getInputStream方法,定义空字符串并输出;通讯完毕,添加socket.close()方法;----try-catch捕获异常

           

客户端
public Class Client{
     private Socket socket;
     public Client(){
         try{       
             System.out.println("正在链接服务端");
             socket=new Socket("localhost",8088);
             System.out.println("成功链接服务端");
        } catch (IOException e){
            e.printStackTrace();
              }
          }


 public void start(){
          2✌  try{ OutputStream out=socket.getOutputStream();
               OutputStreamWriter osw=new OutputStreamWriter(out);
               bufferedwriter bw=new bufferedwriter(osw);
               printWriter pw=new printWriter(bw);
               
               Scanner scanner=new Scanner(System.in);
               String line=scanner.nextLine();
               if("exit".equals(line)){
                          break;
                }
                    pw.println(line);
                    System.out.println(line); 
       }
          }catch(IOException e){
               e.printStackTrace();
            }finally{
                   try{  
                      socket.close();         
                     }catch(IOException e){
                 e.printStackTrace();
              }
       }
✌
}

 public static void main(String[] args){
         Client client=new Client();
         client.start();                    
      }
}

---------------------------------------------------------------------
服务端:

Class Server{
        private ServerSocket serverSocket; 
        public Server(){
             try{
              System.out.println("正在启动服务端");
              serverSocket=new ServerSocket(8088);
              System.out.println("服务端启动完毕");
                 }catch(IOException e){
                   e.printStackTrace(); 
                 }
       
         public void start(){
            try{
              System.out.println("链接客户端");
              Socket socket=serverSocket.accept();
              System.out.println("与一个客户端连接了");
                      }catch(IOException e){     
                        e.printStackTrace();
客户端
public Class Client{
     private Socket socket;
     public Client(){
         try{       
             System.out.println("正在链接服务端");
             socket=new Socket("localhost",8088);
             System.out.println("成功链接服务端");
        } catch (IOException e){
            e.printStackTrace();
              }
          }


 public void start(){
             OutputStream out=socket.getOutputStream();
             OutputStreamWriter osw=new OutputStreamWriter(out);
             bufferedwriter bw=new bufferedwriter(osw);
             printWriter pw=new printWriter(bw);
               

       }

 public static void main(String[] args){
         Client client=new Client();
         client.start();                    
      }
}

---------------------------------------------------------------------
服务端:

Class Server{
        private ServerSocket serverSocket; 
        public Server(){
             try{
              System.out.println("正在启动服务端");
              serverSocket=new ServerSocket(8088);
              System.out.println("服务端启动完毕");
                 }catch(IOException e){
                   e.printStackTrace(); 
                 }
       
         public void start(){
            try{
              System.out.println("链接客户端");
              Socket socket=serverSocket.accept();
              System.out.println("与一个客户端连接了");
                      }catch(IOException e){     
                        e.printStackTrace();}

              try{2👏InputStrem in=socket.getInputStream();
                InputStreamReader isr=new InputStreamReader(in);
                bufferedReader br=new bufferedReaader(isr);
               
                  
                String line;
                 System.out.println("客户端:"+line);
                        }catch(IOException e){
                               e.printStackTrace();     
                  }finally{
                             try{ 
                          socket.close();
                        }catch(IOException e){
                       e.printStackTrace();    
                   }👏
               };

        
         public static void main(String[] args){
               Server server=new Server();
               server.start();
              }
}
        
       

                 3、实现循环发消息

                   客户端:设置while(true)死循环;

                   服务端:设置printWriter为null;添加br的readLine()方法不等于空时的while循环并输              出;

                 4、 多线程实现多客户端的链接;   

                            客户端:  读取服务端发送消息的线程并启动, 

                  a.  start方法(new serverHandler对象 ,实例化线程设置守护线程并启动); 

                  b.  添加ServerHandler类,实现Runnable重写run方法;

                  c.run方法:获取getInputStream方法,添加读取br.readLine()!=null的循环并输出;

                 5、服务端发送消息给客户端;

                            服务端: 

                a、start方法中,new一个客户端处理程序clientHandler对象、实例化thread并启动;   

                b、添加ClientHandler类实现Runnable重写run方法,在run方法加入getInputStream()方

         法和getOutputStream方法。

                c、在clientHandler类中,定义成员变量socker/host,添加clientHandler的有参构造方法;

                  6、服务器转发所有消息给客户端;

                    a. 定义一个list类型的allOut集合;

                    b.在clientHandler类中添加sendMessage有参方法,发送消息并用增强for循环遍                        历,加入同步块;

                    c.广播上线消息: run方法中,将加入输出流pw的allOut的add方法中,设置同步块;

           广播下线信息:在客户端发送消息后面加入pw的allOut 的remove方法,并设置同步块;

                           

           d.代码:

   四、服务端操作流程;

              关键在于new文件与处理流两处的不同;

服务器处理流程代码思路笔记

UserController类---类注解;

       保存所有用户信息目录/static静态块;

    一, reg方法--------注解@RequestMapping;

          1.解析请求;

                 a.  生成对象HttpservletRequest.HttpServletResponse;

                 b.  getparameter获取表单;

          2. 处理请求;------  数据验证

          3. 发送响应;------   sendRedirect方法重定向;

                a.若为空,,, new user对象//重载file构造器;

                b.验证存在性,

                                    若存在,重定向have_user.html;

                c. 流处理,writeObject()方法保存文件; 注册成功响应重定向;

-----------------------------------------------------------------------------------------------------------------------

       二、   login方法

1.请求对象;----获取表单         

2.处理请求;

         a. 数据验证;

         b.若为null,根据用户名去users目录下定位, new file;

         c. 验证存在性,

                  反序列化该文件;把readObject()方法进行强制转换为user,

          看当前密码与注册密码是否一致;

3.发送响应;

          若一致,则发送响应重定向,login_success.html;

若失败,响应重定向为login_fail.html;

-----------------------------------------------------------------------------

       三、   userList方法---------注解@RequestMapping; 

        请求对象;

      1. 准备在页面上展示的数据

                   读取目录信息;----------------list集;

                   获取目录下的.obj文件;--file数组;

        处理请求;

        2.  存入userList集合备用:将obj文件的user对象反序列化,强转,存入userList集合;

        发送响应;

        3、 向浏览器发送html代码;(两个常用方法;)

                setContentType()方法 : 设置发送到客户端的响应的内容类型;

                getWriter()方法:  返回Servlet引擎创建的字符输出流对象

笔记:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值