Java第十八课_线程和网络

发布时间 2023-12-26 21:42:02作者: 张心野

1.线程

  • 线程的休眠

        public static void main(String[] args) {
            // 线程的休眠
            // 第一种方式(不推荐):
            try {
                Thread.sleep(3000);// 毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 第二种方式 :
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
  • 插队

    
        public static void main(String[] args) {
            // 联合/插队 : join(); 其他线程先暂停, 让join线程先运行一段时间
    
            Thread thread = new Thread(() -> {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + "  ::  " + i);
                }
            }
            );
    
            thread.start();
    
            try {
                for (int i = 100; i < 130; i++) {
                    if (i == 108) {
                        System.out.println("插队开始....");
                        thread.join(0, 5);
                        System.out.println("时间到,插队结束~~~~~~~~~~~~~~~~~~~~~....");
                    }
                    System.out.println(Thread.currentThread().getName() + "  ::  " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
  • 礼让

        public static void main(String[] args) {
    
            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
            // 线程的礼让 : yield(); , yield线程先暂停, 让其他线程先运行一段时间
            Thread thread = new Thread(() -> {
                for (int i = 0; i < 40; i++) {
                    System.out.println(Thread.currentThread().getName() + " ::: " + i + " ~~~ " + Thread.currentThread().getPriority());
                }
            });
            thread.setPriority(Thread.MIN_PRIORITY);
            thread.start();
    
            new Thread(() -> {
                for (int i = 100; i < 140; i++) {
                    System.out.println(Thread.currentThread().getName() + " ::: " + i + " ~~~ " + Thread.currentThread().getPriority());
                }
            }).start();
    
            for (int i = 200; i < 240; i++) {
                System.out.println(Thread.currentThread().getName() + " ::: " + i);
                Thread.yield(); // 看起来像是没有暂停时, 是因为其他线程的运行未出结果
                System.out.println(Thread.currentThread().getName() + " ::: " + i);
            }
        }
    
  • 线程安全01

    public class Ticket {
    
        private Integer id;
    
        public Ticket(Integer id) {
            this.id = id;
        }
    
        public Integer getId() {
            return id;
        }
    
        @Override
        public String toString() {
            return "Ticket{" +
                    "id=" + id +
                    '}';
        }
    }
    
    public class Station {
    
        private static List<Ticket> tickets = new ArrayList<>();
    
        static {
            for (int i = 0; i < 30; i++) {
                tickets.add(new Ticket(i + 1));
            }
        }
    
        public List<Ticket> getTickets() {
            return tickets;
        }
    }
    
    public class Practice01 {
    
        public static void main(String[] args) {
            /*
                线程安全问题:
                    多人同时买票, 多线程下如何保证票不重卖
    
                同步代码块 : 各线程使用到锁内资源时, 只能一个个单独访问(相当于多线程执行锁内代码时, 变回了单线程)
                 synchronized (锁) {
                    需要被同步的代码;
                 }
    
                 锁对象 : 所有线程看到的是同一个对象才会生效
                    1.字符串/String : 不推荐使用
                    2.当前类的字节码文件
                    3.this
             */
            Station station = new Station();
    
            SaleStationA saleStation = new SaleStationA(station);
    
            Thread thread1 = new Thread(saleStation,"飞猪");
            Thread thread2 = new Thread(saleStation,"携程~~~~~~");
            Thread thread3 = new Thread(saleStation,"12306");
            Thread thread4 = new Thread(saleStation,"去哪^_^");
    
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
        }
    }
    
    public class SaleStationA implements Runnable{
    
        private Station station;
    
        public SaleStationA(Station station) {
            this.station = station;
        }
    
        @Override
        public void run() {
            List<Ticket> tickets = station.getTickets();
            System.out.println(Thread.currentThread().getName() + " :: " + this);
            while (tickets.size() > 0) {
                // synchronized (锁)
                synchronized (this) {
                    if (tickets.size() > 0) {
                        Ticket ticket = tickets.remove(0);
                        System.out.println(Thread.currentThread().getName() + " A卖出了一张票 , 票号为 : " + ticket.getId());
                    }
                }
                // 模拟消耗时间
                try {
                    TimeUnit.MILLISECONDS.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  • 线程安全02

    public class Practice02 {
        public static void main(String[] args) {
            /*
                锁的第二种实现方式:
                同步函数 :
                synchronized 返回值类型  函数名(){}
    
                锁对象 :
                    普通函数的锁对象是 this
                    静态函数的锁对象是当前类的字节码文件
             */
            Station station = new Station();
    
            SaleStationB saleStation1 = new SaleStationB(station);
            SaleStationB saleStation2 = new SaleStationB(station);
            SaleStationB saleStation3 = new SaleStationB(station);
            SaleStationB saleStation4 = new SaleStationB(station);
    
            Thread thread1 = new Thread(saleStation1,"飞猪");
            Thread thread2 = new Thread(saleStation2,"携程~~~~~~");
            Thread thread3 = new Thread(saleStation3,"12306");
            Thread thread4 = new Thread(saleStation4,"去哪^_^");
    
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
        }
    }
    
    public class SaleStationB implements Runnable{
    
        private Station station;
    
        public SaleStationB(Station station) {
            this.station = station;
        }
    
    
        @Override
        public void run() {
            List<Ticket> tickets = station.getTickets();
            System.out.println(Thread.currentThread().getName() + " :: " + this);
            while (tickets.size() > 0) {
    
                saleTicket(tickets);
                // 模拟消耗时间
                try {
                    TimeUnit.MILLISECONDS.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 同步函数 :synchronized
        public static synchronized void saleTicket(List<Ticket> tickets){
            if (tickets.size() > 0) {
                Ticket ticket = tickets.remove(0);
                System.out.println(Thread.currentThread().getName() + " B卖出了一张票 , 票号为 : " + ticket.getId());
            }
        }
    }
    
  • 线程安全03

    public class Practice03 {
    
        public static void main(String[] args) {
            /*
                锁的第三种实现方式:
                    Lock:
                        用法类似第一种, 加上Lock声明, 之后的资源就只能单独访问了
                        有效访问到lock.unlock();为止
             */
    
            Station station = new Station();
    
            Lock lock = new ReentrantLock();
    
            SaleStationC saleStation1 = new SaleStationC(station,lock);
            SaleStationC saleStation2 = new SaleStationC(station,lock);
            SaleStationC saleStation3 = new SaleStationC(station,lock);
            SaleStationC saleStation4 = new SaleStationC(station,lock);
    
            Thread thread1 = new Thread(saleStation1,"飞猪");
            Thread thread2 = new Thread(saleStation2,"携程~~~~~~");
            Thread thread3 = new Thread(saleStation3,"12306");
            Thread thread4 = new Thread(saleStation4,"去哪^_^");
    
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
        }
    }
    
    public class SaleStationC implements Runnable{
    
        private Lock lock;
        private Station station;
    
        public SaleStationC(Station station ,Lock lock) {
            this.lock = lock;
            this.station = station;
        }
    
        @Override
        public void run() {
            List<Ticket> tickets = station.getTickets();
            System.out.println(Thread.currentThread().getName() + " :: " + this);
            while (tickets.size() > 0) {
    
                try {
                    // Lock
                    lock.lock();
                    if (tickets.size() > 0) {
                        Ticket ticket = tickets.remove(0);
                        System.out.println(Thread.currentThread().getName() + " C卖出了一张票 , 票号为 : " + ticket.getId());
                    }
                } finally {
                    lock.unlock();// 需要unlock声明锁到哪里
                }
                // 模拟消耗时间
                try {
                    TimeUnit.MILLISECONDS.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  • 死锁

    public class Practice04 {
    
        public static void main(String[] args) {
            // 死锁 :
            // A 线程已经 占用 了 x 资源 , 需要 y资源才能继续执行 , 此时 , B线程 占有 y资源 ,需要 x资源才能继续执行
            class MyThread implements Runnable{
                @Override
                public void run() {
                    String name = Thread.currentThread().getName();
                    if ("小明".equals(name)) {
                        synchronized ("筷子A") {
                            System.out.println(name + " 持有筷子 A , 需要筷子B 才能吃东西");
                            synchronized ("筷子B") {
                                System.out.println("小明开始吃饭....");
                            }
                        }
                    }
                    if ("老王".equals(name)) {
                        synchronized ("筷子B") {
                            System.out.println(name + " 持有筷子 B , 需要筷子A 才能吃东西");
                            synchronized ("筷子A") {
                                System.out.println("老王      开始吃饭....");
                            }
                        }
                    }
                }
            }
    
            Thread thread1 = new Thread(new MyThread(), "小明");
            Thread thread2 = new Thread(new MyThread(), "老王");
            thread1.start();
            thread2.start();
        }
    }
    

2.网络

  • InetAddress

        public static void main(String[] args) throws UnknownHostException {
            // InetAddress : 此类表示互联网协议 (IP) 地址。
            // static InetAddress getLocalHost()
            //           返回本地主机信息。
            // UnknownHostException
            InetAddress inetAddress = InetAddress.getLocalHost();
    
            System.out.println("inetAddress = " + inetAddress);// 辉/192.168.1.2
            System.out.println("inetAddress.getHostAddress() = " + inetAddress.getHostAddress());// 192.168.1.2
            System.out.println("inetAddress.getHostName() = " + inetAddress.getHostName());// 电脑名
            System.out.println("inetAddress.getAddress() = " + inetAddress.getAddress());// [B@4554617c
            System.out.println("Arrays.toString(inetAddress.getAddress()) = " + Arrays.toString(inetAddress.getAddress()));
            //  [-64, -88, 1, 2]  : 192 - 128 - 128
    
            InetAddress byAddress = InetAddress.getByAddress(new byte[]{-64, -88, 1, 2});
            System.out.println("byAddress = " + byAddress);
    
            InetAddress byName = InetAddress.getByName("LAPTOP-D5AN7N74");
            System.out.println("byName = " + byName);
        }
    
  • Server和Client

    public class Server {
    
        public static void main(String[] args) throws IOException {
            // 1.创建服务器对象
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2.开启侦听功能,等待客户端连接
            System.out.println("服务器已启动,等待客户端链接......");
            Socket socket = serverSocket.accept();
            // 3.获取输入流,读取客户端发送过来的信息
            InputStream inputStream = socket.getInputStream();
            // 包装为字符缓冲流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String info = bufferedReader.readLine();
            System.out.println("我是服务端 , 客户端跟我说 : " + info);
    
            // 4.获取输出流响应客户端
            OutputStream outputStream = socket.getOutputStream();
            // 包装为字符缓冲流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            String serverInfo = "lisi , 你好!! ";
            bufferedWriter.write(serverInfo);
            bufferedWriter.flush();
    
            // 5.资源释放
            bufferedWriter.close();
            outputStream.close();
            bufferedReader.close();
            inputStream.close();
            socket.close();
            serverSocket.close();
        }
    }
    
    public class Client {
    
        public static void main(String[] args) throws IOException {
            // 当前主机的表示形式 : 1.localhost  2.   127.0.0.1   3.IP地址 :  192.168.1.2
            // 1.客户端对象
            Socket socket = new Socket("localhost", 8888);// 主机和端口号都是服务器
            // 2.获取输出流发送信息
            OutputStream outputStream = socket.getOutputStream();
            // 3.包装为字符缓冲流, 向服务器发送信息
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            String info = "username=lisi&password=123";
            bufferedWriter.write(info);
            bufferedWriter.flush();
            socket.shutdownOutput();
    
            // 4.获取输入流,读取服务器信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String clientInfo = bufferedReader.readLine();
            System.out.println("我是客户端 , 服务器对我说  : " + clientInfo);
    
            // 5.释放资源
            bufferedReader.close();
            bufferedWriter.close();
            inputStream.close();
            outputStream.close();
            socket.close();
        }
    }
    
  • Server和Client02

    public class Server {
    
        public static void main(String[] args) throws IOException {
            // 1.创建服务器对象
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2.开启侦听功能,等待客户端连接
            System.out.println("服务器已启动,等待客户端链接......");
            Socket socket;
            while (true) {
                socket = serverSocket.accept();
                new Thread(new ServerThread(socket)).start();
            }
        }
    }
    
    public class ServerThread implements Runnable{
    
        private Socket socket;
    
        public ServerThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            // 3.获取输入流,读取客户端发送过来的信息
            InputStream inputStream = null;
            // 包装为字符缓冲流
            BufferedReader bufferedReader = null;
            // 4.获取输出流响应客户端
            OutputStream outputStream = null;
            // 包装为字符缓冲流
            BufferedWriter bufferedWriter = null;
            try {
                inputStream = socket.getInputStream();
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    
                String info = bufferedReader.readLine();
                System.out.println("我是服务端 , 客户端跟我说 : " + info);
    
                // 提取用户名
                String[] split = info.split("&");
                String[] split1 = split[0].split("=");
                String username = split1[1];
    
                // 获取用户 IP 地址
                InetAddress inetAddress = socket.getInetAddress();
    
                outputStream = socket.getOutputStream();
    
                bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
                String serverInfo = username + " , 你好!! 您的IP地址为 : " + inetAddress.getHostAddress();
                bufferedWriter.write(serverInfo);
                bufferedWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    bufferedReader.close();
                    inputStream.close();
                    bufferedWriter.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
        }
    }
    
    public class Client {
    
        public static void main(String[] args) throws IOException {
            // 当前主机的表示形式 : 1.localhost  2.   127.0.0.1   3.IP地址 :  192.168.1.2
            // 1.客户端对象
            Socket socket = new Socket("192.168.31.116", 8888);// 主机和端口号都是服务器
            // 2.获取输出流发送信息
            OutputStream outputStream = socket.getOutputStream();
            // 包装为字符缓冲流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            String info = "username=kitty&password=123";
            bufferedWriter.write(info);
            bufferedWriter.flush();
            socket.shutdownOutput();
    
            // 3.获取输入流,读取服务器信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    
            String clientInfo = bufferedReader.readLine();
            System.out.println("我是客户端 , 服务器对我说  : " + clientInfo);
    
            // 4.释放资源
            bufferedReader.close();
            bufferedWriter.close();
            inputStream.close();
            outputStream.close();
            socket.close();
        }
    }
    
  • 爬虫

    public class Practice {
    
        public static void main(String[] args) throws IOException {
            // MalformedURLException
            // URL
            URL url = new URL("https://baike.baidu.com/item/%E6%A0%B9%E5%9F%9F%E5%90%8D%E6%9C%8D%E5%8A%A1%E5%99%A8/5907519?fromtitle=%E6%A0%B9%E6%9C%8D%E5%8A%A1%E5%99%A8&fromid=136331");
    
            InputStream inputStream = url.openStream();
    
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
    
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("baidu.html"));
    
            int len;
            byte[] bytes = new byte[1024 << 2];
            while ((len = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, len);
            }
            bufferedOutputStream.flush();
    
            bufferedOutputStream.close();
            bufferedInputStream.close();
            inputStream.close();
        }
    }