第五天Java基础(异常、线程)

1.异常(Excption)

1.1 异常分类

1.Exception:编译异常
2.RuntimeException:运行异常
3.Error:错误

1.2异常的两种处理方式

1.抛出异常,JVM处理异常,如果发现异常直接中断程序,控制台打印异常。

throws ParseException {
	//把异常交给JVM处理
}

2.自行处理异常

	try {
            date = sf.parse("1999-1203000");
        }catch (ParseException e){
            e.getErrorOffset();
        }

3.异常抛出的处理流程
在这里插入图片描述

1.2 关键字(throw)

1.写在方法内部
2.new的对象必须是Exception或是其子类

throw new NullPointerException("抛异常");

3.我们必须对方法传递过来的参数进行合法性的校验,如果不合法就抛异常。

1.3Object非空判断

Objects.requireNonNull(obj,“异常描述”);//该方法对对象进行非空校验,如果为空直接抛异常。

1.4关键字(throws)

1.必须写在方法声明处。
2.声明的对象必须是Exception或是其子类。
3.方法抛出多个异常对象,throws也必须声明多个异常。
4.必须处理异常。(自己处理,或者jvm中断程序)

1.5关键字(try_catch)

1.try中可能会抛出多个异常对象,那么就需要使用多个catch,来捕获异常,
2.try代码中一但出现异常,就会执行catch去处理错误,然后继续执行后续代码。

1.6Throwable类中定义的三个异常处理方法

1.getMessage();//返回简短信息
2.toString();//详细信息
3.printStackTrace();//全面信息

 try {

        }catch (Exception e){
            e.getMessage();//简短
            e.toString();//详细信息
            e.printStackTrace();//全面信息
        }

1.7(关键字)finally

try{}catch(){}finally{
	//无论是否出现异常都会执行
	//主要用于资源释放
}

1.8 异常的注意事项

1.如果异常类型出现父子关系,那么子类必须写在前面。
2.父类可以同时接收子类的异常。
3.如果finally中出现return关键字返回的结果都是finally中的结果
4.父类异常怎么了,子类异常就怎么样

1.9 自定义的异常类

1.自定义的异常类一定要继承Exception / RuntimeException
2.Exception 编译期异常
3.RuntimeException 运行异常

2 多线程

2.1 并发,并行

1.并发:多个事件在同一个时间段内发生。(交替执行)
2.并行:多个事件在同一个时刻内发生。(同时执行)

2.2 线程,进程

1.进程:进入到内存中的程序。
2.线程:线程是属于进程中的一个执行单元。

2.3 线程调度

1.分时调度:平均分配cpu使用时间
2.抢占式调度:工具优先级分配cpu使用时间

2.4 主线程

1.执行主方法的线程

2.5 多线程(Thread)常用的方法

1.getName();//获取线程名称
2.start();//开启线程
3.run();//重写线程方法
4.currentThread();//获取当前执行的线程,静态
5.Thread.currentThread().getName();//获取当前执行的线程,并打印名称
6.setName();//设置线程名称
7.在线程的子类中创建一个带参构造方法String name,super(name)把线程名字传递给Thread,也可以设置线程名。
8.Thread.sleep(1000);//线程暂停时间

2.6 多线程(Runnable)常用的方法

1.runnable开启线程的方式
实现Runnble接口,RunnbleImpl run = new RunnbleImpl();
创建Thread的构造方法,把run传进去,Thread t = new Thread(run);
然后开启线程
2.Runnable的好处
避免单继承的局限性
增强了程序的扩展性,降低类耦合性,把设置任务和开启线程进行分离

2.7 匿名内部类,简化线程代码

1.new Thread(){ run(){ … } }.start();
2.new Thread(new Runnale(){ run( … ) }).start();

2.8 线程安全问题

1.多线程在操作同一个资源时,会出现线程安全问题。
2.如何解决,同步技术
synchronized(锁对象){
//代码块
}

int count = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while(true){
            synchronized(obj){
                if(count>0){
                    System.out.println(Thread.currentThread().getName()+",在买第"+count+"张票!");
                    --count;
                }else{
                    break;
                }
            }
        }
    }

3.如何解决,同步方法
也是synchronized关键字,把产生线程安全问题的代码放入其中
同步方法:public synchronized void xxx(){}
其锁对象是this
4.静态同步方法:public static synchronized void xxx(){}
其锁对象是本类的class属性,class文件对象。
5.lockes锁 :
lockes锁比synchronized 锁 好一点。
其中两个方法比较重要
lock();//获取锁
unlock();//释放锁

Lock l =new ReentrantLock();
l.lock();//获取锁
l.unlock();//释放锁

3.线程状态

1.新建状态 new
2.运行状态 Runnable
3.阻塞状态 Blocked
4.死亡状态 Terminated
5.休眠状态 Timed_waiting
6.无限等待 Waiting
运行状态的线程可以通过
Object.wait()方法进入无限等待状态
可以通过Object.notify()恢复运行状态,或者是休眠状态

4.等待唤醒案例

public static void main(String[] args) {
        Object o = new Object();
        new Thread(){
            @Override
            public void run() {
                    while(true){
                        synchronized (o){
                            System.out.println("老板我要包子一个!");
                            try{
                                o.wait();
                            }catch(InterruptedException e){
                                System.out.println(e.getMessage().toString());
                            }
                            System.out.println("-------------------------------");
                            System.out.println("吃包子!");
                        }
                    }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while(true){
                    try{
                        Thread.sleep(5000);
                    }catch(InterruptedException e){
                        System.out.println(e.getMessage().toString());
                    }
                    synchronized (o){
                        System.out.println("包子好了!");
                        o.notify();
                    }
                    System.out.println();
                }
            }
        }.start();
    }

5.Object类中wait带参数的方法

1.obj.wait(5000);//相当于Thread.sleep(5000);
2.唤醒线程的两种方法,obj.notify();//唤醒一个等待线程,obj.notifyall();//唤醒所有等待的线程

5.线程通信

1.主要通过锁对象调用,obj.notify();和obj.wait();

6.等待与唤醒

1.等待与唤醒机制必须在同步锁当中。

 @Override
            public void run() {
                    while(true){
                        synchronized (o){
                            System.out.println("老板我要包子一个!");
                            try{
                                o.wait();
                            }catch(InterruptedException e){
                                System.out.println(e.getMessage().toString());
                            }
                            System.out.println("-------------------------------");
                            System.out.println("吃包子!");
                        }
                    }
            }
///////////////////////////////////////////////
 @Override
            public void run() {
                while(true){
                    try{
                        Thread.sleep(5000);
                    }catch(InterruptedException e){
                        System.out.println(e.getMessage().toString());
                    }
                    synchronized (o){
                        System.out.println("包子好了!");
                        o.notify();
                    }
                    System.out.println();
                }
            }

5.线程池(Executors)

1.使用线程池的工厂类Executors里面提供的newFixedThreadPool生产一个指定数量的线程池
2.创建一个类来实现Runable,重写run();
3.调用ExecutorService中的方法submit,传递线程任务,开启线程执行run方法

ExecutorService es = Executors.newFixedThreadPool(2);
es.submit(new RunnableImpl);
es.shutdown();//销毁线程池
# 5.线程池(Executors)

6.Lambda表达式

1.主要简化匿名内部类的写法

		new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("普通写法");
            }
        }).start();
        new Thread(() -> {
            System.out.println("Lambda表达式");
        }).start();

2.省略规则
(参数列表):括号中参数列表类型,可以省略
(参数列表):括号中的参数只有一个,那么类型的()都可以省略
(一些代码):如果代码只有一行,无论是否有返回值都可以省略({},return,分号)注意一定要一起省略

 new Thread(()-> System.out.println("sss")).start();
 //////////////////////////////
 Arrays.sort(arr, (Pan o1, Pan o2) -> o1.getAge() - o2.getAge());

3.Lambda的使用前提
使用必须具有接口,且接口必须仅有一个抽象方法
方法的参数或者局部变量必须为接口类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值