java SE_7

1. Properties的使用、 属性文件:

properties(用于存放键值对数据的一种文件类型)

  • 测试

    // Properties --属性﹐对应一种文件格式
    //xx. properties文件,叫属性文件。
    // **文件内容格式: key=value ,等号前面是键﹐等号后面是值。一个键值对是一行。
    public class TestProperties {
    	public static void main(String[] args) throws IOException {
    		// 1.创建对象
    		Properties p = new Properties();
    		// 2.添加数据
    		p.setProperty("yw", "100");
    		p.setProperty("sx", "90");
    		// 3.取出数据
    		System.out.println(p.getProperty("yw"));
    		System.out.println(p.getProperty("sx"));
    
    		// 4.通过io流,加载一个本地属性文件﹐把文件内容保存Properties对象中。
    		System.out.println("--------a.properties-----");
    		FileInputStream fis = new FileInputStream("E:\\Desktop\\Games\\HQYJ\\Projects\\javase\\src\\day7\\a.properties");
    		Properties p1 = new Properties();
    		p1.load(fis);
    
    		Set<Map.Entry<Object, Object>> entries = p1.entrySet();
    		entries.forEach(System.out::println);
    		System.out.println("根据key找value: " + p1.get("username"));
    	}
    }
    
  • 属性文件:a.properties

    yw=100
    sx=90
    yy=80
    hx=70
    username=root1
    password=123456
    port=3306
    dbname=crm
    

2. 线程

1. 什么是线程

  1. java程序支持多线程,并且java中的多线程处理较为简单。一般操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序被称为进程,当程序运行时候,内部可能包含多个顺序流执行,每个顺序执行流就是一个线程。

2. 线程类型

  1. Thread类代表线程类型
  2. 任何线程对象都是Thread类(子类)的实例
  3. Thread类是线程的模板(封装了复杂的线程开启等操作,封装了操作系统的差异性等)
  4. 只要重写run方法,就可以实现具体线程。

3. 具体实现

1 . 继承Thread类
  1. 创建一个类,继承Thread类

  2. 重写run方法,实现用户字自己的过程

  3. 创建线程实例(即子类的对象) ,通过start方法,启动线程,线程启动之后,会尽快执行run方法

  • 测试

    public class ThreadDemo2 {
       public static void main(String[] args) throws InterruptedException {
          //创建对象
          MyThread t1 = new MyThread();
          AnthorThread t2 = new AnthorThread();
          //设置线程优先级
          t1.setPriority(Thread.MAX_PRIORITY);
          t2.setPriority(Thread.MIN_PRIORITY);
          //启动线程 : 调用start方法,启动了线程。然后线程会自动调用自己的run方法。
          t1.start(); // 表示线程进入到:runnable状态,即可运行状态。 这个时候如果cpu分配了时间片,然后线程就调用run方法。
          t2.start();
    
          Thread.sleep(3000); // main对应的线程等待3秒。
    
          System.out.println(t1.isAlive());
          System.out.println(t2.isAlive());
       }
    }
    
    /*public class Thread implements Runnable {}*/
    class MyThread extends Thread {
       //通过重写run方法,设置线程的功能。
       @Override
       public void run() {
          System.out.println("hello Thread");
       }
    }
    
    class AnthorThread extends Thread {
       @Override
       public void run() {
          System.out.println("你好, 世界");
       }
    }
    
2. 通过使用Runnable接口,创建线程
  1. 创建一个类,实现Runnable接口, 重写run 方法

  2. 以实现了Runnable接口的类的实例,作为创建Thread类的参数。

  • 测试

    //定义三个线程关型
    //**第一个每隔500毫秒,说一句:要下课了,重复500次
    //  第二个每隔300毫秒,说一句:中午吃什么,重复500次
    //  第三个每隔100毫秒:说一句:写作业,重复500次
    //Thread . sleep(时间) --等待多久。
     //最后观察程序执行过程。
    public class ThreadDemo3_1 {
       public static void main(String[] args) {
          B b = new B();
          Thread t = new Thread(b);
          t.start(); //启动线程类
          //System.out.println(b);
          //Date d = new Date(System.currentTimeMillis());
          //System.out.println(d);
          //使用匿名内部类
          Thread t1 = new Thread(new Runnable() {
             @Override
             public void run() {
                for (int i =0; i < 50; i++){
                   System.out.println("要下课了");
                   try {
                      Thread.sleep(50);
                   } catch (InterruptedException e) {
                      e.printStackTrace();
                   }
                }
             }
          });
          t1.start();
    
          Thread t2 = new Thread(() -> {
             for (int i = 0; i < 50; i++) {
                System.out.println("中午吃什么");
                try {
                   Thread.sleep(30);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
             }
          });
          t2.start();
    
          Thread t3 = new Thread(() -> {
             for (int i = 0; i < 50; i++) {
                System.out.println("写作业");
                try {
                   Thread.sleep(10);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
             }
          });
          t3.start();
       }
    }
    //创建自己的线程
    //①extends 继承Thread
    //② 写一个类,实现Runnable接口
    class A{
       void print(){
          System.out.println("Hello");
       }
    }
    
    //实现了Runnable接口, 不能说B是线程类
    class B extends A implements Runnable{
       //int k;  //什么时候能用?
       void print(){
          System.out.println("Hello");
       }
    
       @Override
       public void run() {
          Thread t = Thread.currentThread();  // 获取当前线程
          System.out.println(t.getName() + "--------" + t.getId());
          //计算出1~100的和
          int sum = 0;
    
          for(int i = 1; i <= 100; i++){
             try {
                Thread.sleep(1000);
             } catch (InterruptedException e) {
                e.printStackTrace();
             }
             sum += i;
          }
          //this.k = sum;
          System.out.println("和:" + sum);
       }
    }
    
3. Callable接口
  • 测试

    import java.util.concurrent.Callable; //接口
    import java.util.concurrent.ExecutorService; //接口
    import java.util.concurrent.Executors;  //工具类
    import java.util.concurrent.Executor;// 接口
    import java.util.concurrent.ThreadPoolExecutor;  //实现类
    
    //ThreadPool : 线程池
    public class ThreadPoolDemo {
       public static void main(String[] args) {
          //*** newFixedThreadPool  -- 创建固定个数的线程池
          ExecutorService es = Executors.newFixedThreadPool(2);
          //参数是Runnable
          es.submit(() -> {
             Thread thread = Thread.currentThread();
             System.out.println(thread.getName() + "----" + thread.getId());
             for (int i = 0; i < 10; i++) {
                try {
                   Thread.sleep(100);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
                System.out.println("-----------1-------------");
             }
          });
          //参数是Callable
          es.submit(new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName() + "----" + thread.getId());
                for (int i = 0; i < 10; i++) {
                   try {
                      Thread.sleep(100);
                   } catch (InterruptedException e) {
                      e.printStackTrace();
                   }
                   System.out.println("-----------2-------------");
                }
                return 100;
             }
          });
    
          //参数是Callable
          es.submit(() -> { // lambda 表达式
             Thread thread = Thread.currentThread();
             System.out.println(thread.getName() + "----" + thread.getId());
             for (int i = 0; i < 10; i++) {
                try {
                   Thread.sleep(100);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
                System.out.println("-----------3-------------");
             }
             return 100;
          });
    
          es.shutdown(); // 关闭线程池
       }
    }
    
4. 守护线程
  1. 守护线程是指在线程运行前,将线程设置为守护线程,那么当程序中没有其他线程运行时候,jvm退出,程序就终止。

  2. 测试

    // 守护线程
    public class ThreadDemo4 {
       public static void main(String[] args) {
          Thread t1 = new Thread(() -> {
             // 每隔10毫秒输出:"xxxxxxxx"
             for (int i = 0; i < 100; i++) {
                try {
                   Thread.sleep(10);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
                System.out.println("介绍xx产品:......." + i);
             }
          });
          t1.start();
          Thread t2 = new Thread(() -> {
             // 每隔10毫秒输出:"xxxxxxxx"
             for (int i = 0; i < 1000; i++) {
                try {
                   Thread.sleep(10);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
                System.out.println("刷了一个轮船......." + i);
             }
          });
          t2.setDaemon(true); // 启动之前,设置其为守护线程。
          t2.start();
       }
    }
    
5. 线程对象的方法
  • //** java支持多线程:多个程序干不同的事情.  怎么创建多个线程
    //** 之前的程序中,没有创建出多线程对象,那么就只有一个线程(main方法对应的线程)在工作:单线程程序
    public class ThreadDemo {
       public static void main(String[] args) {
          //获取当前线程
          Thread thread = Thread.currentThread(); // main方法对应的线程
          //线程di
          System.out.println(thread.isDaemon()); //每个线程有一个唯一的id
          //线程名字
          System.out.println(thread.getName());
          //线程的优先级
          System.out.println(thread.getPriority());//优先级高的线程,cpu分配的时间片就多,优先运行。
          //线程的状态
          System.out.println(thread.getState());
          //是否活着
          System.out.println(thread.isAlive()); // RUNNABLE 可运行的
          //是否为守护线程(精灵线程):被守护的线程结束了,守护线程也就结束了
          System.out.println(thread.isDaemon());
    
       }
    }
    
6. 线程的状态
7. sleep方法
  • Thread.sleep(times) 使当前线程从running放弃处理器,进入block状态,休眠times毫秒,再进入runnable状态。
  • image-20230812102528175
8. 线程同步
  1. 异步: 并发,线程间互不影响,自己干自己的。
  • 测试

    import java.util.Date;
    public class SynchronizedDemo1 {
       public static void main(String[] args) {
          //记录程序开始时间,记录每个线程结束的时间(最后的结束时间,就是整个程序运行的结束时间
          System.out.println("线程结束:" + new Date()); // main方法对应的主线程
          Thread t1 = new Thread(() -> {
             add("小红");
             //System.out.println("线程结束:" + new Date(System.currentTimeMillis())); 由于Date的空参构造函数的返回值为: this(System.currentTimeMillis());
             System.out.println("线程结束:" + new Date());
          });
          Thread t2 = new Thread(() -> {
             add("小黄");
             System.out.println("线程结束:" + new Date());
          });
          Thread t3 = new Thread(() -> {
             add("小名");
             System.out.println("线程结束:" + new Date());
          });
          t1.start();t2.start();t3.start();//线程的并发
       }
    
       public static void add(String str) { //方法没有上锁,异步
          try {
             Thread.sleep(5000); //等5秒
          } catch (InterruptedException e) {
             e.printStackTrace();
          }
          System.out.println("Hello:" + str);
       }
    }
    
  1. 所谓同步,就是指在调用某个功能的时候,在没有得到结果之前,该调用不返回,同时其他线程无法使用这个功能。步调一致的处理,有序地执行。

    • 多个线程并发读写同一个临界资源的时候,会发生“线程并发安全问题”,使用同步代码块,解决并发安全问题.

    • synchronized可以修饰方法,表示整个方法修的全部内容需要同步。
      synchronized(同步监视器){ // … } ,
      同步监视器一般是一个对象。尽量减小同步范围,提高并发的效率。

      image-20230812104629582

    • 测试

      import java.util.Date;
      public class SynchronizedDemo2 {
      	public static void main(String[] args) {
      		//记录程序开始时间,记录每个线程结束的时间(最后的结束时间,就是整个程序运行的结束时间
      		System.out.println("线程结束:" + new Date()); // main方法对应的主线程
      		Thread t1 = new Thread(() -> {
      			add("小红");
      			System.out.println("线程结束:" + new Date());
      		});
      		Thread t2 = new Thread(() -> {
      			add("小黄");
      			System.out.println("线程结束:" + new Date());
      		});
      		Thread t3 = new Thread(() -> {
      			add("小名");
      			System.out.println("线程结束:" + new Date());
      		});
      		t1.start();t2.start();t3.start();//线程的并发
      	}
      
      	public static void add(String str) { //方法上锁,同步
      		try {
      			Thread.sleep(5000); //等5秒
      		} catch (InterruptedException e) {
      			e.printStackTrace();
      		}
      		/*
      		synchronized(this){
      			for (int i = 0; i < 100; i++) {
      				System.out.println("Hello:" + str);
      			}
      		}
      		*/
      	}
      }
      
      

3. Socket编程

CS架构:

  1. 在C/S模式下,客户向服务器端发出请求,服务器端接收到请求之后,提供相应的服务。

  2. 客户端部分: 每个用户都有自己的客户端,负责发送请求。

  3. 服务端部分: 多个用户共享一个服务器,处理每个客户端的请求。

  4. ServerSocket & Socket

    image-20230812105035700

  • 测试

    • Server

      //服务器端的程序
      public class Server {
         private ServerSocket server;
      
         //构造函数: 初始化成员变量
         public Server() {
            System.out.println("开始初始化....");
            try {
               // 端口号。程序启动的时候,会占用一个端口号,
               // 通过端口号找到对应的程序
               server = new ServerSocket(9999);
            } catch (IOException e) {
               e.printStackTrace();
            }
            System.out.println("初始化完成....");
         }
      
         //启动服务器: 等待客户端连接,然后给客户提供服务。
         public void start() throws IOException {
            while (true) {
               System.out.println("等待客户端连接....");
               //这个引用指向的就是当前连接上的客户端的Socket
               Socket client = server.accept();
               InetAddress inetAddress = client.getInetAddress();
               String ip = inetAddress.getHostAddress();
               int port = client.getPort();
               System.out.println(ip + "---" + port + "连接成功");
               //io操作  -- 服务器接受消息
               InputStream in = client.getInputStream();
               InputStreamReader isr = new InputStreamReader(in);
               BufferedReader br = new BufferedReader(isr);
               String word = br.readLine();
               System.out.println(ip + ":" + port + "说:" + word);
            }
         }
      
         public static void main(String[] args) throws IOException {
            //创建服务器端
            Server s = new Server();
            s.start();
         }
      }
      
    • Client

      //客户端的程序
      public class Client {
         private Socket socket;
         public Client(){
            System.out.println("开始连接服务器....");
            try {
               //host:主机
               //port:端口
               //localhost:特殊的字符串,代表的就是你的电脑的域名
               //127.0.0.1: 特殊的ip, 代表的就是你电脑的ip
               //new Socket:是为了找到主机上的某个软件。
               //要找的服务器软件就在这个电脑上,所以使用localhost
               //要找的主机上的软件的端口号是9999
               socket = new Socket("localhost",9999);
            } catch (IOException e) {
               e.printStackTrace();
            }
            System.out.println("连接服务器成功....");
         }
         //启动客户端
         public void start() throws IOException {
            //io操作 -- 客户端给服务器发消息
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(out);
            BufferedWriter bw = new BufferedWriter(osw);
            bw.write("你好服务器,我叫小红。");
            bw.flush();
            bw.close();
         }
      
         public static void main(String[] args) throws IOException {
            //创建客户端
            Client c = new Client();
            c.start();
         }
      }
      

4. review

1. 线程的创建方式有哪些?

  1. 继承Thread类:通过创建一个继承自Thread类的子类,然后重写**run()**方法来定义线程要执行的任务。

    image-20230812111142833

  2. 实现Runnable接口:通过实现Runnable接口,重写run()方法,然后将实现了Runnable接口的对象传递给Thread类的构造函数。

    image-20230812111415382

  3. 实现Callable接口:通过实现Callable接口,重写call()方法,然后将实现了Callable接口的对象传递给Thread类的构造函数。它允许线程执行任务并返回结果,同时也支持抛出异常。

    image-20230812111628637

2. Runnable 接口和 Callable接口的区别?

  1. 返回值:
    • Runnable接口的**run()**方法没有返回值,因此任务执行后无法获取任务的执行结果
    • Callable接口的**call()**方法可以返回一个结果,可以是任何类型。
  2. 异常抛出:
    • **run()**方法不能直接抛出受检查的异常,但可以通过在方法内部捕获异常。
    • **call()**方法可以抛出受检查的异常,因为它允许使用者捕获异常并处理。
  3. 使用方式:
    • Runnable通常与Thread或者线程池结合使用,用于执行异步任务,但不关心任务的返回值。
    • Callable通常与ExecutorService结合使用,允许获取线程任务的返回值,并能处理任务抛出的异常
  4. 灵活性:
    • 由于Runnable没有返回值,它更适合简单的线程任务,不需要返回结果的情况。
    • Callable提供了更大的灵活性,以为它允许返回结果并处理异常,适用与需要详细控制任务执行和获取结果的情况。
  5. Java版本:
    • Runnable接口在较早的Java版本中就已经存在,而Callable接口是在Java5中引入的,作为并发包的一部分。

在选择使用Runnable还是Callable时,你可以根据任务的的性质和需求来决定。如果你需要执行简单的异步任务而不需要返回结果,那么使用Runnable更为合适。如果你需要获取任务的结果,处理异常,或者需要更大的灵活性,那么使用Callable会更好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值