Day 66

_生产者和消费者案例<代码有误,正在调试>

  1. 生产者消费者案例中包含的类:

    • 奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
    • 生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
    • 消费者类(Customer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
    • 测试类(BoxDemo):里面有main方法,main方法中的代码步骤如下:
      • 创建奶箱对象,这是共享数据区域
      • 创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中需要调用存储牛奶的操作
      • 创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中需要调用存储牛奶的操作
      • 创建两个线程,分别把生产者对象和消费者对象作为构造方法参数传递
      • 启动线程
  2. package demo20;
    
    public class Application {
        public static void main(String[] args) {
            /*
            生产者消费者案例中包含的类:
            - 奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
            - 生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
            - 消费者类(Customer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
            - 测试类(BoxDemo):里面有main方法,main方法中的代码步骤如下:
              - 创建奶箱对象,这是共享数据区域
              - 创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中需要调用存储牛奶的操作
              - 创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中需要调用存储牛奶的操作
              - 创建两个线程,分别把生产者对象和消费者对象作为构造方法参数传递
              - 启动线程
             */
    
            Box b = new Box();
    
            // 创建生产者和消费者对象
            Producer producer = new Producer(b);
            Customer customer = new Customer(b);
    
            Thread t1 = new Thread(producer);
            Thread t2 = new Thread(customer);
    
            // 启动线程
            t1.start();
            t2.start();
        }
    }
    -------------------------------------------------
    package demo20;
    
    public class Producer implements Runnable {
        private Box b ;
    
        public Producer(Box b) {
            this.b = b;
        }
        @Override
        public void run() {
            for (int i = 1; i <= 5; i++) {
                b.put(i);
            }
        }
    }
    ------------------------------------------
    package demo20;
    
    public class Customer implements Runnable{
        private Box b;
    
        public Customer(Box b) {
            this.b = b;
        }
        @Override
        public void run() {
            b.get();
        }
    }
    -----------------------------------------
    package demo20;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Box {
        /*
        奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
         */
        private int milk;
        private int milkBox = 0;
        Lock lock = new ReentrantLock();
        // 定义一个成员变量,表示奶箱的状态,默认为关闭状态
        private boolean state = false;
    
        public synchronized void put(int milk) {
            this.milk = milk;
            if (milkBox < 1) {
                milkBox++;
                System.out.println("送奶工放入第" + milk + "瓶牛奶");
                System.out.println("此时奶箱中有"+milkBox+"瓶牛奶");
                // 唤醒所有线程
                lock.notifyAll();
            }else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public synchronized void get() {
            this.milk = milk;
            if (milkBox >= 1) {
                milkBox--;
                System.out.println("客人取出第" + milk + "瓶牛奶");
                System.out.println("此时奶箱中有"+milkBox+"瓶牛奶");
                // 唤醒所有线程
                lock.notifyAll();
            }else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    ==========================================
        
    

_IP地址

  1. 常用命令:(在Dos命令窗口中)
    • ipconfig:查看本机的IP地址
    • ping IP地址:检查网络是否连通

_InetAddress

  1. 为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress供我们使用

  2. InetAddress:此类表示Internet协议(IP)地址

  3. 方法名说明
    static InetAddress getByName(String host)确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
    String getHostName()获取IP地址的主机名称
    String getHostAddress()返回文本显示中的IP地址字符串
  4. package demo21;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class IP_Demo_01 {
        public static void main(String[] args) {
            /*
            1. 为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress供我们使用
    
            2. InetAddress:此类表示Internet协议(IP)地址
    
            3.
            static InetAddress getByName(String host)     确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
            String getHostName()                          获取IP地址的主机名称
            String getHostAddress()                       返回文本显示中的IP地址字符串
             */
    
            try {
                InetAddress address = InetAddress.getByName("192.169.10.3");
                String IP = address.getHostAddress();
                String name = address.getHostName();
    
                System.out.println("主机名称:"+name);
                System.out.println("IP地址:" + IP);
    
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
    
        }
    }
    ==========================================
    主机名称:192.169.10.3
    IP地址:192.169.10.3
    
    Process finished with exit code 0
    

_UDP发送数据

  1. 发送数据的步骤:

    • 创建发送端的Socket对象(DatagramSocket) // socket:插座
      • DatagramSocket()
    • 创建数据,并把数据打包
      • DatagramPacket(byte[] buf , int length , InetAddress , int port)
    • 调用DatagramSocket对象的方法发送数据
      • void send(DatagramPacket p)
    • 关闭发送端
      • void close()
  2. package demo21;
    
    import java.io.IOException;
    import java.net.*;
    
    public class UDP_Demo_01 {
        public static void main(String[] args) {
            /*
            发送数据的步骤:
            - 创建发送端的Socket对象(DatagramSocket)     // socket:插座
              - DatagramSocket()
            - 创建数据,并把数据打包
              - DatagramPacket(byte[] buf , int length , InetAddress , int port)
            - 调用DatagramSocket对象的方法发送数据
              - void send(DatagramPacket p)
            - 关闭发送端
              - void close()
             */
    
            /*
            public class DatagramSocket
            此类表示用于发送和接收数据报数据包的套接字。
            数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。
            从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。
             */
    
            try {
                DatagramSocket ds = new DatagramSocket();
    
    
                // 创建数据,并把数据打包
                //  - DatagramPacket(byte[] buf , int length , InetAddress , int port)
                byte[] bytes = "hello,Internet,I am coming".getBytes();
                int length = bytes.length;
                InetAddress inetAddress = InetAddress.getByName("198.168.10.3");
    
                // 打包
                DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, 10086);
    
                // 调用DatagramSocket对象的方法发送数据
                ds.send(dp);
    
                // 关闭发送端
                ds.close();
    
    
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ===================================
    
    Process finished with exit code 0
    

_UDP接收数据

  1. 接收数据的步骤:

    • 创建接收端的Socket对象(DatagramSocket)
      • DatagramSocket(int port)
    • 创建一个数据包,用于接收数据
      • DatagramPacket(byte[] buf ,int length)
    • 解析数据包,并把数据在控制台显示
      • byte[] getData()
      • int getLength()
    • 关闭接收端
      • void close
  2. package demo21;
    
    import java.io.IOException;
    import java.net.*;
    
    public class Send_Demo {
        public static void main(String[] args) {
            /*
            发送数据的步骤:
            - 创建发送端的Socket对象(DatagramSocket)     // socket:插座
              - DatagramSocket()
            - 创建数据,并把数据打包
              - DatagramPacket(byte[] buf , int length , InetAddress , int port)
            - 调用DatagramSocket对象的方法发送数据
              - void send(DatagramPacket p)
            - 关闭发送端
              - void close()
             */
    
            /*
            public class DatagramSocket
            此类表示用于发送和接收数据报数据包的套接字。
            数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。
            从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。
             */
    
            try {
                DatagramSocket ds = new DatagramSocket();
    
    
                // 创建数据,并把数据打包
                //  - DatagramPacket(byte[] buf , int length , InetAddress , int port)
                byte[] bytes = "hello,Internet,I am coming".getBytes();
                int length = bytes.length;
                InetAddress inetAddress = InetAddress.getByName("192.168.10.3");
    
                // 打包
                DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, 10086);
    
                // 调用DatagramSocket对象的方法发送数据
                ds.send(dp);
    
                // 关闭发送端
                ds.close();
    
    
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    -------------------------------------------
    package demo21;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class Receive_Demo {
        public static void main(String[] args) {
            /*
            接收数据的步骤:
            - 创建接收端的Socket对象(DatagramSocket)
              - DatagramSocket(int port)
            - 创建一个数据包,用于接收数据
              - DatagramPacket(byte[] buf ,int length)
            - 解析数据包,并把数据在控制台显示
              - byte[] getData()
              - int getLength()
            - 关闭接收端
              - void close
             */
    
            try {
                // 创建接收端的Socket对象(DatagramSocket)
                DatagramSocket ds = new DatagramSocket(10086);
    
                // 创建一个数据包,用于接收数据
                // DatagramPacket(byte[] buf ,int length)
                byte[] bytes = new byte[1024];
                int length = bytes.length;
                DatagramPacket dp = new DatagramPacket(bytes, length);
    
                // 调用DatagramSocket对象的方法来接收数据
                /*
                public void receive(DatagramPacket p)
                 throws IOException
                 从此套接字接收数据报包。
                 当此方法返回时, DatagramPacket的缓冲区将填充接收到的数据。
                 数据包数据包还包含发送者的IP地址和发件人机器上的端口号。
                 */
                ds.receive(dp);
    
                // 解析数据包,并把数据在控制台显示
                // 返回数据缓冲区
                // byte[] getData()
                byte[] data = dp.getData();
                // 返回接收数据的长度
                int len = dp.getLength();
    
                // 将byte类型的接收数据转换成String类型的数据
                /*
                public String(byte[] bytes,  int offset,  int length)
                通过使用平台的默认字符集解码指定的字节子阵列来构造新的String 。
                新的String的长度是字符集的函数,因此可能不等于子数组的长度。
                指定字节在默认字符集中无效时,此构造函数的行为是未指定的。
                当需要更多的解码过程控制时,应使用CharsetDecoder类。
                 */
                String dataString = new String(data, 0, len);
    
                // 将接收到的数据显示到控制台上
                System.out.println("接收到的数据:" + dataString);
    
                // 关闭接收端
                ds.close();
    
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ==============================================
    接收到的数据:hello,Internet,I am coming
    
    Process finished with exit code 0
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值