JavaSE第十四天




复习:
线程:
   两种实现方式:
       extends  Thread   
       implements Runnable 不是线程类
   构造方法:
       Thread();
       Thread(String name);
       Thread(Runnable r);
       Thread(Runnable r,String name)
   常用方法:
       run()线程体方法
       start()启动线程
       currentThread()返回正在执行的线程对象
       getName()返回线程的名称
       sleep() 线程休眠
       join()等待线程执行结束
   生命周期:
       新建状态:new Thread()
       就绪状态:start()
       阻塞状态:sleep(),wait(),io,解除,重新排队
       运行状态:run()执行方法,自动执行的
       消亡状态:执行完run方法
   优先级:
       系统自动分配:5
       人为设置:
   调度:
       不同优先级:高优先级先执行,低后
       同一优先级:先到先服务
   线程同步:
       共享变量不安全
       synchronized
        synchronized(锁对象){
           
        }
        synchronized修饰方法
   同步线程之间的通信问题
       wait()
       notify();
       notifyAll();
-------------------------------------------------------------
sleep和wait的区别

   sleep线程类的方法       wait是Object类的方法
   sleep方法不是释放锁     wait是释放锁
   sleep方法自动醒         wait必须使用notify,notifyAll唤醒
 

线程的死锁
StringBuffer str1 = new StringBuffer();
        StringBuffer str2 = new StringBuffer();
        synchronized (str1) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (str2){
                System.out.println("str1");
                System.out.println("str2");
            }
        }
        synchronized (str2) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (str1){
                System.out.println("str1");
                System.out.println("str2");
            }
        }

线程池
   为什么使用线程池
     频繁的创建线程,需要耗费时间和内存
   使用线程池的好处:
     管理线程
     使线程重用

package cn.tedu.demo.thread;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPoolDemo {
    //创建一个线程池,如果线程池中的线程数量过大,它可以有效的回收多余的线程,
    //            如果线程数不足,那么它可以创建新的线程。
    public static void test1() throws Exception {
        
        ExecutorService threadPool = Executors.newCachedThreadPool();
    
        for (int i = 0; i < 5; i++) {
    
            final int index = i;
    
            Thread.sleep(1000);
            //完成5个任务
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "  " + index);
                     try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    //指定线程池中的线程数,线程数是可以进行控制的
    public static void test2() throws InterruptedException {
        
       // ExecutorService threadPool = Executors.newFixedThreadPool(1);
        ExecutorService threadPool =
                Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
    
            Thread.sleep(1000);
            final int index = i;
    
            threadPool.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "  " + index);
            });
        }
        threadPool.shutdown();//不关闭正在执行的线程
          //threadPool.shutdownNow();//不管线程是否执行完毕,立即停止执行
          System.out.println("关闭线程!");
    }
    //线程池支持定时周期性任务执行
    public static void test3() {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
    
        threadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                long start = new Date().getTime();
                System.out.println("scheduleAtFixedRate 开始执行时间:" +
                        DateFormat.getTimeInstance().format(new Date()));
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                long end = new Date().getTime();
                System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m");
                System.out.println("scheduleAtFixedRate 执行完成时间:" + DateFormat.getTimeInstance().format(new Date()));
                System.out.println("======================================");
            }
        }, 1, 5, TimeUnit.SECONDS);
    }
    //单线程池,至始至终都由一个线程来执行
    public static void test4() {
    
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
    
        for (int i = 0; i < 5; i++) {
            final int index = i;
            threadPool.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "   " + index);
            });
        }
       // threadPool.shutdown();
    }
    
    public static void main(String[] args) throws Exception {
        test2();

    }

}
-------------------------------------------------------------
网络编程概述
    计算机网络:


    网络模型(OSI开放式系统互联。国际标准组织制定了OS七层网络模型I(Open System Interconnection)模型)
                  OSI七层网络模型
        物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
        
    协议:事先规定好的通信规则
        
        协议分类:共有的,私有的
                网络层:ip
                传输层:udp,tcp
                应用层:ftp http https。。。

    IP地址
        IP地址:表示网络上的唯一一台计算机
        IP地址分为两个版本:
                  IPv4    IPv6
            
    端口:0-65535    (0-1024)预留的
        
    域名解析:localhost(www.163.com):127.0.0.1(72.1.1.1)
        

java中的网络编程
    
    1.UDP通信 -- 写信
        不需要创建连接
        通过发送数据包通信 每个数据包最大64KB
        不可靠的传输机制
        传输速度比较快
        追求速度快 可靠性要求不高的场景下 - 视频聊天

        
    2.TCP通信 -- 打电话
        需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手
        底层通过 流 发送数据 数据没有大小限制
        可靠的传输机制 - 丢包重发 包的顺序的保障
        传输速度相对比较慢
        对于速度要求不太高 但是对可靠性要求比较高的场景下 - 文件上传 下载

        因为TCP在通信的过程中 是需要创建连接的 连接的发起者称为客户端 监听端口等待被连接的一端称为服务端

服务器端的核心代码

    //1.创建套接字对象
        ServerSocket serverSocket=
                new ServerSocket(5555);
        System.out.println("等待客户端的请求。。。。。");
        //2.调用accept方法,接收请求
        Socket socket = serverSocket.accept();
        System.out.println("接收到一个客户端的请求。。。。。。");
        //3.获取输入流对象,读客户端的数据
        InputStream in = socket.getInputStream();
        BufferedReader br =
                new BufferedReader(
                    new InputStreamReader(in));
        String msg = br.readLine();
        System.out.println(msg);
        //4.处理后的结果通过输出流,写出去
        msg = msg+ " hello,client!";
        OutputStream out = socket.getOutputStream();
        PrintStream pw = new PrintStream(out);
        pw.println(msg);
        pw.flush();
        
        //5.关闭流,套接字对象
        br.close();
        pw.close();
        socket.close();
        serverSocket.close();

 客户端的代码:
     //1.创建套接字对象
        Socket socket = new Socket("localhost",5555);
        //2.获取输出流,写信息
        OutputStream out =
                socket.getOutputStream();
        PrintStream pw =
                new PrintStream(out);
        pw.println("hello server!");
        pw.flush();
        //3.获取输入流,读信息
        InputStream in = socket.getInputStream();
        BufferedReader br =
                new BufferedReader(
                        new InputStreamReader(in));
        String msg = br.readLine();
        System.out.println(msg);
        //4.关闭流
        
        pw.close();
        br.close();
        socket.close();    


    
        案例(了解):实现 文件 上传服务器

作者:赵瑞鑫。支持原创,从你我做起。
原文地址:https://www.cnblogs.com/Winer-Jiu/p/13428170.html