Day24知识总结

Properties的使用

Properties 属性,对应一种文件格式,即xx.properties文件,属性文件

文件格式内容 key=value
等号前是键,等号后是值
一个键值对是一行,键与值均为String类型
Properties是一种格式、一种文件类型

创建对象: Properties p=new Properties();
插入数据: 对象.setProperty(key,value) 键与值均为String类型
即:p.setProperty(“yw”,“80”);
查询数据:对象.getProperty(key) 或 对象.get(Object)
即:p.getProperty(“yw”)
键值对集合:对象.entrySet();

基本方法使用

创建、插入、查询

 		//创建对象
        Properties p=new Properties();
        p.setProperty("yw","80");//插入数据
        p.setProperty("sx","90");
        //查询数据
        System.out.println(p.getProperty("yw"));
        System.out.println(p.getProperty("sx"));

读取xx.properties文件,遍历输出

a.properties

FileInputStream fis=new FileInputStream("E:\\IDEA_DATA\\javadata1\\javadata_one\\javase\\src\\day7\\a.properties");
        //通过io流,加载本地文件并将文件内容保存至Properties对象中
        Properties p1=new Properties();
        p1.load(fis);
        Set<Map.Entry<Object, Object>> en = p1.entrySet();//entrySet键值对
        en.forEach(System.out::println);
        //根据key找value
        System.out.println(p1.get("dd"));

线程Thread

java支持多线程的,多个程序做不同的事情
一个进程[大的任务]可包含许多线程[各个小的流程]

一个进程多个线程

Thread对象的基础方法

Thread类代表线程类型
任何线程对象都是Thread类(子类)的实例

Thread类是线程的模板
(封装了复杂的线程开启等操作,封装了操作系统的差异性等)

只要重写run方法,就可以实现具体线程

获取当前线程:Thread.currentThread();
获取线程id:对象.getId(); 每一个线程有一个唯一的id
获取线程名字:对象.getName()
获取线程的优先级:对象.getPriority(); 返回类型int
线程的优先级设置,最小为1,最大为10,默认为5
获取线程的状态:对象.getState(); 返回类型State类型
是否活着:对象.isAlive() 返回boolean
是否为守护线程(精灵线程):对象.isDaemon() 返回boolean
守护线程的生命周期,取决于被守护的线程是否存活着

单线程程序
Main方法也是一个线程

public class Demo2ThreadDemo {
    public static void main(String[] args) {
        //获取当前线程
        Thread thread = Thread.currentThread();//Main方法对应的线程;
        //获取线程id[变量.getId()]每一个线程有一个唯一的id
        System.out.println(thread.getId());//1
        //获取线程名字[变量.getName()]
        System.out.println(thread.getName());//main
        //获取线程的优先级[变量.getPriority() 返回类型int]
        //优先级高的线程,cpu分配的时间片就多,优先运行
        System.out.println(thread.getPriority());//5
        //获取线程的状态 [对象.getState() 返回类型State类型]
        System.out.println(thread.getState());//RUNNABLE
        //是否活着[对象.isAlive() 返回boolean]
        System.out.println(thread.isAlive()); //true
        //是否为守护线程(精灵线程)[对象.isDaemon() 返回boolean]
        //守护线程的生命周期,取决于被守护的线程是否存活着
        System.out.println(thread.isDaemon());//false
    }
}

继承Thread类

创建一个类,继承Thread类
重写run方法,实现子类的线程过程

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

启动线程[对象.start()方法]

调用start()方法,即启动线程,线程会自动调用自己的run方法
表示线程进入到runnable,即运行状态;此时若cup分配了时间片,即线程就调用run方法
线程运行的先后顺序,由cpu决定;线程自己做自己的事
Main方法也对应一个线程;

多线程程序

//任何线程对象否是Thread类(子类)的实例
//只要重写run()方法,就可以实现具体线程
//线程的优先级设置,最小为1,最大为10,默认为5

//多线程程序:
//main方法对应的线程,t1,t2
public class Demo3Thread {
    public static void main(String[] args) {
        //创建对象
        Thread t1=new MyThread();
        Thread t2=new AnthorThread();
        //设置[修改]线程的优先级 最小为1,最大为10,默认为5
        t2.setPriority(10);
        //启动线程[对象.start()方法]
        //调用start()方法,即启动线程,线程会自动调用自己的run方法
        //表示线程进入到runnable,即运行状态。此时若cup分配了时间片,即线程就调用run方法
        //线程运行的先后顺序,由cpu决定;线程自己做自己的事
        t1.start();
        t2.start();
        System.out.println(t1.isAlive());
        System.out.println(t2.isAlive());
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("hello Thread");
    }
}
class AnthorThread extends Thread{
    @Override
    public void run() {
        System.out.println("你好,世界");
    }
}

通过使用Runnable接口,创建线程

创建一个类,实现Runnable接口, 重写run 方法
以实现了Runnable接口的类的实例,作为创建Thread类的参数

Runnable接口函数式接口,可以使用lambda函数,无参返回

由于Thread中有一个构造器为:

public Thread(Runnable实现类的对象)

因此,创建线程对象

//方法一
B b=new B();//B是Runnable接口的实现类
Thread t=new Thread(b);
//方法二
//匿名函数
Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {//代码块}
        }
 //方法三 lambda表达式
 Thread t2=new Thread(()-> {
            //代码块
        }
//写一个类,实现Runnable接口
//public Thread(Runnable实现类的对象)
//Runnable接口函数式接口,可以使用lambda函数

//多线程:每个线程都在做自己的事情,由cup来调度
//新建、可运行、等待、计时等待[Thread.sleep()]、终止、阻塞
//唤醒notify()、notifyAll()

//synchronized,同步的,保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行
//新建线程对象,调用start()方法启动线程,等待cpu调度进入线程运行。线程完成即终止;若未完成,进入阻塞再次等待cpu调度直至完成后终止。

public class Demo3ThreadTest1 {
    public static void main(String[] args) {
        B b=new B();
        Thread t=new Thread(b);
        t.start();//启动线程
        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();
                    }
                }
            }
        });
        Thread t2=new Thread(()->{
            for (int i=0;i<50;i++){
                System.out.println("中午吃什么");
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread t3=new Thread(()->{
            for (int i=0;i<50;i++){
                System.out.println("写作业");
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
        t3.start();

    }
}
class A{
    void print(){
        System.out.println("++++++");
    }
}
//实现了Runnable接口,不能说是B是线程类
class B extends A implements Runnable{

    @Override
    public void run() {
        Thread t=Thread.currentThread();
        System.out.println(t.getName()+"---"+t.getId());
        int sum=0;
        for (int i=1;i<=100;i++){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sum+=i;
        }
        System.out.println(sum);
    }
}

Callable接口

Thread pool 线程池 Runnable、Callable

Executors.newFixedThreadPool()创建固定个数的线程池

线程占满时,有新任务进来需要等待;在有空闲线程时,再放入刚刚在等待的新任务

参数是Callable 泛型且有返回值Future类型的 lambda表达式
线程池中线程运行完后,需要自动关闭,对象.shutdown();


import java.util.concurrent.Callable;//函数式接口
import java.util.concurrent.Executor;//接口
import java.util.concurrent.ExecutorService;//接口
import java.util.concurrent.Executors;//工具类
//import java.util.concurrent.ThreadPoolExecutor; //实现类

//Callable
//Thread pool 线程池  Runnable、Callable
public class Demo5ThreadPool {
    public static void main(String[] args) {
        //Executors.newFixedThreadPool()创建固定个数的线程池
        ExecutorService es = Executors.newFixedThreadPool(2);
        //线程占满时,有新任务进来需要等待;在有空闲线程时,再放入刚刚在等待的新任务
        //此处参数为Runnable 没有返回值的
        es.submit(()->{
            Thread t=Thread.currentThread();//找到当前线程
            System.out.println(t.getName()+"-----"+t.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 t=Thread.currentThread();//找到当前线程
                System.out.println(t.getName()+"-----"+t.getId());
                for (int i=0;i<10;i++){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("---------2----------");
                }
                return 100;
            }
        });
        //参数是Callable 泛型且有返回值Future类型的 lambda表达式
        //由于只有两个线程,因此第三个线程需要等待满线程有空闲,才能开始运行
        es.submit(()-> {
            Thread t=Thread.currentThread();//找到当前线程
            System.out.println(t.getName()+"-----"+t.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();//当线程池中线程运行完后,需要自动关闭
    }
}
class A1 implements Callable{

    @Override
    public Object call() throws Exception {
        return null;
    }
}

守护线程

守护线程是指在线程运行前,将线程设置为守护线程,那么当程序中没有其他线程运行时候,jvm退出,程序就终止

可以有许多守护线程存在

守护线程不是指守护某一个正常线程,而是当所有正常线程执行完后,即使守护线程还没执行完,但会随着在所有正常线程执行完而被强制终止

必须在启动线程之前,设置其为守护线程

对象.setDaemon(true)

public class Demo4Thread {
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
            for (int i=1;i<=100;i++){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("介绍xx产品:....."+i);
            }
        });
        t1.start();//正常线程
        Thread t2=new Thread(()->{
            for (int i=1;i<=1000;i++){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("刷了一个轮船:....."+i);
            }
        });
        //启动之前,设置其为守护线程
        t2.setDaemon(true);//设置线程的守护线程[对象.setDaemon]
        t2.start();
        //当正常线程t1结束后,即使守护线程t2没有运行完,也会与之一起终止
        //可以有许多守护线程存在
        //守护线程不是指守护某一个正常线程,而是当所有正常线程执行完后,即使守护线程还没执行完,但会随着在所有正常线程执行完而被强制终止。

    }
}

守护线程

线程的状态

线程状态

睡眠与唤醒

睡眠:Thread.sleep(times)

使当前线程从running放弃处理器,进入block状态,休眠times毫秒,再进入runnable状态

唤醒:notify()、notifyAll()

notify()方法的基本思想是给方法或代码块提供一种相互通信的方式,而这些方法或者代码块同步于某个特定对象
代码块可以调用wait()方法来将自身的操作挂起

挂起:wait()

线程同步

synchronized,同步的,保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行

所谓同步,就是指在调用某个功能的时候,在没有得到结果之前,该调用不返回,同时其他线程无法使用这个功能

异步: 并发,线程间互不影响,自己干自己的
同步: 步调一致的处理,有序地执行

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

synchronized修饰方法

synchronized可以修饰方法,表示整个方法修的全部内容需要同步。

public class Demo6Synchronized1 {
    public static void main(String[] args) {
        //记录程序开始,记录每个线程结束时间(最后的结束时间就是整个程序运行时间)
        System.out.println("程序开始"+new Date(System.currentTimeMillis()));
        Thread t1=new Thread(()->{//匿名函数Runnable()接口 lambda
            add("小红");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        Thread t2=new Thread(()->{//匿名函数Runnable()接口 lambda
            add("小黄");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        Thread t3=new Thread(()->{//匿名函数Runnable()接口 lambda
            add("小明");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        t1.start();
        t2.start();
        t3.start();
    }
    public static synchronized void add(String str){
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello"+str);
    }
}

synchronized(同步监视器){}

synchronized(同步监视器){ // … } ,同步监视器一般是一个对象

//synchronized 关键字 修饰方法 大范围局限
//synchronized() 方法 小范围局限
//安全性低效率高、安全性高效率低
public class Demo6Synchronized2 {
    public static void main(String[] args) {
        //记录程序开始,记录每个线程结束时间(最后的结束时间就是整个程序运行时间)
        System.out.println("程序开始"+new Date(System.currentTimeMillis()));
        Thread t1=new Thread(()->{
            add("小红");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        Thread t2=new Thread(()->{
            add("小黄");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        Thread t3=new Thread(()->{
            add("小明");
            System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        });
        t1.start();
        t2.start();
        t3.start();
    }
    public static void add(String str){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (Demo6Synchronized2.class){
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello"+str);
            //System.out.println("程序结束"+new Date(System.currentTimeMillis()));
        }

    }
}

Socket

CS架构:

在C/S模式下,客户向服务器端发出请求,服务器端接收到请求之后,提供相应的服务。
客户端部分: 每个用户都有自己的客户端,负责发送请求。
服务端部分: 多个用户共享一个服务器,处理每个客户端的请求

框架

Server

服务器端,ServerSocket


//服务器端的程序
public class Demo7Server {
    private ServerSocket server;

    //构造函数:初始化成员变量server
    public Demo7Server(){
        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+"..."+"连接成功");
            //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 {
        Demo7Server s=new Demo7Server();
        s.start();
    }
}

Client

客户端,Socket

//客户端的程序
public class Demo7Client {
    private Socket socket;
    public Demo7Client(){
        System.out.println("开始连接服务器...");
        try {
            socket=new Socket("localhost",9999);
            //host主机:ip与port端口号
            //"localhost" 自己电脑的域名,127.0.0.1 特殊ip
            //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 {
        Demo7Client c=new Demo7Client();
        c.start();
    }
}

面试题

ArrayList的扩容机制

ArrayList每次扩容50%;
初始大小为10;

ArrayList和数组转换

数组转ArrayList: 通过 Arrays.asList转换
ArrayList转数组: 通过集合的toArray()转换

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值