Day16

Day 16

一、线程优先级

Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应
调度哪个线程来执行。

线程的优先级用数字表示,范围从1到10。

一个线程的默认优先级是5。

setPriority(int newPriority) 改变这个线程的优先级

注意:优先级低只是意味着获得调度的概率低。并不是绝对先调用优先级高后调用优先级低的线程。

public class ThreadDemo01 implements Runnable{
   public static void main(String[] args) {
      ThreadDemo01 demo = new ThreadDemo01();
      Thread th1 = new Thread(demo,"A");
      Thread th2 = new Thread(demo,"B");
      Thread th3 = new Thread(demo,"C");
      
      //设置优先级
      th1.setPriority(Thread.MIN_PRIORITY);  
      th3.setPriority(10);
      
      th1.start();  
      th2.start();
      th3.start();
      
      //查看优先级
      System.out.println(th1.getPriority());
      System.out.println(th2.getPriority());
      System.out.println(th3.getPriority());
   }

   @Override
   public void run() {
      System.out.println(Thread.currentThread().getName());
   }
}

二、线程通信

同步问题的典型示例是“生产者-消费者”模型,也就是生产者线程只负责生产,消费者线程只负责消费,在消费者发现无内容可消费时则睡觉

  • 线程通信 生产者消费者模式

    wait() 等待 当一个线程wait,会进入到对象的等待池中,等待被唤醒

    让出cpu的资源,让出 对象锁资源

    notify() 唤醒随机一个 唤醒对象等待池中的线程,被唤醒的线程会进入到就绪状态,满足使用条件才可以使用

    notifyAll() 唤醒全部

    必须要使用在一个同步的环境下

public class Demo03 {
   public static void main(String[] args) {
      Street street = new Street();
      //人线程  车线程
      new Thread(new Person(street)).start();
      new Thread(new Car(street)).start();
   }
}

//街道资源
class Street{
   //红绿灯
   private boolean flag = false;
   
   //东西->人 -->false
   public void we() {
      //true-->wait()
      if(flag != false) {
         try {
            this.wait();  //当前线程进入到this对象的等待池中
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }else {   //人走
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
         System.out.println("人走......");
         //改变信号灯   唤醒对方
         flag = true;
         this.notify();
      }
   }
   
   
   //南北 --> 车 -->true
   public void ns() {
      //false-->wait()
      if(flag != true) {
         try {
            this.wait();  //当前线程进入到this对象的等待池中
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }else {   //车走
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
         System.out.println("车走......");
         //改变信号灯   唤醒对方
         flag = false;
         this.notify();
      }
   }
}


class Person implements Runnable{
   //资源
   private Street street;
   
   public Person(Street street) {
      this.street = street;
   }

   @Override
   public void run() {
      while(true) {
         street.we();
      }
      
   }
}


class Car implements Runnable{
   //资源
   private Street street;
   
    public Car(Street street) {
       this.street = street;
   }

   @Override
   public void run() {
      while(true) {
         street.ns();
      }
   }
}

如何解决死锁问题:

  1. 往往是程序逻辑的问题。需要修改程序逻辑。
  2. 尽量不要同时持有两个对象锁

三、网络编程

网络编程:底层 数据如何传输,使用哪种协议

网页编程: 上层

网络编程:

​ 1)如何定位到一台电脑 – IP(人的身份证号码) 定位网络上的节点(电子设备)

​ 2)如何区分多个软件 – (端口)

​ 3)如何区分一个软件中的多个资源 – url

共组织内部使用的额非注册IP: 192.168.0.0 ~ 192.168.255.255

127.0.0.1 本机IP

localhost ->本机

public class NetDemo01 {
   public static void main(String[] args) throws UnknownHostException {
      //static InetAddress getLocalHost() 返回本地主机的地址。  
      InetAddress i1 = InetAddress.getLocalHost();
      System.out.println(i1);   //DESKTOP-P04TCL5/192.168.14.111
      //static InetAddress getByName(String host) 决定了IP地址的主机,主机的名字。  
      InetAddress i2 = InetAddress.getByName("www.baidu.com");
      System.out.println(i2);  //www.baidu.com/180.101.49.12
      
      System.out.println(i1.getHostName());  //DESKTOP-P04TCL5
      System.out.println(i1.getHostAddress());  //192.168.14.111
      
   }
}

四、端口

端口: port – 区分软件

2个字节 0~65535

同一个写一下端口号不能冲突

8000以下的端口号不建议使用–>预留端口号

  • 常见的端口号:

    80 http

    8080 tomcat

    3306 mysql

    1521 oracle

public class PortDemo02 {
   public static void main(String[] args) {
      //InetSocketAddress(int port) 创建一个套接字地址的IP地址在哪里通配符地址和端口号一个指定的值。 
      InetSocketAddress in= new InetSocketAddress("localhost",8888);
      System.out.println(in);
      
      //ip
      System.out.println(in.getHostName());
      //端口号
      System.out.println(in.getPort());
      
   }
}

五、URL

URL : 统一资源定位符

互联网三大基石 : html http url

URL->类

public class URLDemo03 {
   public static void main(String[] args) throws MalformedURLException {
      //URL(String spec) 
      URL url = new URL("http://www.baidu.com:80/index.html?name=zhangsan&pwd=123#a");
      
      System.out.println(url);
      
      //getProtocol()  协议
      System.out.println("协议:"+url.getProtocol());
      System.out.println("域名:"+url.getHost());
      System.out.println("端口:"+url.getPort());
      System.out.println("资源:"+url.getFile());  ///index.html?name=zhangsan&pwd=123
      System.out.println("文件:"+url.getPath());  
      System.out.println("数据:"+url.getQuery());  
      System.out.println("锚点:"+url.getRef());  
      
   }
}

六、传输层协议

* Socket 套接字
*  相当于传输层为应用层开辟的一个小口子
*          不同协议下Socket实现不同
*          面向Socket编程

1.UDP

UDP:UDP(UserDatagramProtocol ) 发送短信 非面向连接、不安全、数据可能丢失 、效率高,只管写只管发送

UDP实现基本流程: 发送端

  • 1.定义发送端 DatagramSocket(int port) 指定发送端ip和端口

  • 2.准备数据–> 转为字节数组

  • 3.打包 DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 构造一个数据报包发送数据包的长度 length抵消 ioffsetto指定主机上的指定端口号。

  • 4.发送数据 send(DatagramPacket p) 从这个套接字发送一个数据报包。

  • 5.关闭

    –文件的传输—> 从本地文件中 读取数据–>传输到对方–>接收到数据–>写出指定本地位置

    public class UDPSend01 {
       public static void main(String[] args) throws IOException {
          System.out.println("--------------我是发送端-----------------------------------");
          //1.定义发送端 DatagramSocket(int port) 指定发送端ip和端口
          DatagramSocket  send = new DatagramSocket(7777);
          //2.数据
          byte[] msg = "千年等一回".getBytes();
          //3.打包
          DatagramPacket  packet = new DatagramPacket(msg,0,msg.length,new InetSocketAddress("localhost", 8888));
          //4.发送
          send.send(packet);
          //5.关闭
          send.close();
       }
    }
    

UDP实现基本流程: 接收端

  • 1.构建接收端
  • 2.准备包裹–>用来接收数据
  • 3.接收
  • 4.处理数据
  • 5.关闭
public class UDPReceive02 {
   public static void main(String[] args) throws IOException {
      System.out.println("--------------我是接收端-----------------------------------");
      //1.构建接收端
      DatagramSocket  receive = new DatagramSocket(8888);
      //2.准备包裹-->用来接收数据
      byte[] arr = new byte[1024*60];
      DatagramPacket  packet = new DatagramPacket(arr,arr.length);
      //3.接收
      receive.receive(packet);
      
      //4.处理数据
      /*
       * byte[] getData() 
                返回数据缓冲区。 
         int getLength() 
                返回将要发送或接收到的数据的长度。 
       */
      byte[] result = packet.getData();
      int length = packet.getLength();
      System.out.println(new String(result,0,length));
      
      //5.关闭
      receive.close();
   }
}

2.TCP

TCP:TCP(transfer control protocol) 打电话 面向连接、安全、可靠,效率低,送端和接受端两端平等

基于 tcp 协议,建立稳定连接的点对点的通信;实时、快速、安全性高、占用系统资源多、效率低;“请求-响应”模式:
a)、客户端:在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序
b)、服务器:第一次通讯中等待连接的程序被称作服务器端(Server)程序
• Socket:发送 TCP 消息
• ServerSocket:创建服务器

服务器:
①创建服务器 指定端口
②等待客户端连接
③分析接收数据

客户端:
①连接服务器: 创建客户端 +指定服务器地址 +端口
②发送数据

TCP 基本流程: 服务端

  • 1.创建服务端 ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 服务端的端口号
  • 2.阻塞式监听
  • 3.获取IO流
  • 4.读入数据
  • 5.操作数据
  • 6.关闭
public class TCPClient03 {
   public static void main(String[] args) throws UnknownHostException, IOException {
      String name = "laopei";
      String pwd = "0523";
      System.out.println("---------------client--------------");
      //1.创建客户端
      Socket client =  new Socket("127.0.0.1",8888);
      //2.获取输入流
      OutputStream os = client.getOutputStream();
      //3.写出数据
      os.write(("name="+name+"&pwd="+pwd).getBytes());
      os.flush();
      
      //获取输入流读取服务端响应
      InputStream is = client.getInputStream();
      byte[] car = new byte[1024];
      int len = is.read(car);
      System.out.println(new String(car,0,len));
      
      //4.关闭
      is.close();
      os.close();
      client.close();
   }
}
public class TCPServer04 {
   public static void main(String[] args) throws IOException {
      System.out.println("---------------Server--------------");
      //1.创建服务端
      ServerSocket server = new ServerSocket(8888);
      //2.阻塞式监听
      Socket client = server.accept();
      System.out.println("-----------有一个客户端连接成功-------------------");
      
      //3.获取IO流  
      InputStream is = client.getInputStream();
      
      //4.读入数据
      byte[] car = new byte[1024];
      //把数据读入到字节数组car中,返回值len为读入到字节数组中真实数据的长度
      int len = is.read(car);
      
      String name =null;
      String pwd =null;
      //5.操作数据
      String str = new String(car,0,len);
      //分割数据  name=laopei&pwd=0523
      String[] arr = str.split("&");
      for(String s:arr) {
         String[] ss = s.split("=");
         //判断当前这个ss[1]是名字的值还是密码的值
         if("name".equals(ss[0])) {
            name = ss[1];
         }else {
            pwd = ss[1];
         }
      }
      System.out.println(name);
      System.out.println(pwd);
      
      //获取输出流
      OutputStream os = client.getOutputStream();
      
      //校验
      if("laopei".equals(name) && "0523".equals(pwd)) {
         os.write("登录成功".getBytes());
      }else {
         os.write("shibai".getBytes());
      }
      os.flush();
      //6.关闭
      os.close();
      is.close();
      client.close();
      server.close();
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值