1.例外
1.0 例外的概念

2.throw關鍵字

public class Main{
public static void main(String[] args) {
int []arc=null;
getelem(arc,0);
}
private static int getelem(int arc[],int index) {
if(arc==null){
throw new NullPointerException("空指標例外!");
}
return arc[index];
}
}

public class Main{
public static void main(String[] args) {
int []arc=new int[3];
getelem(arc,3);
}
private static int getelem(int arc[],int index) {
if(arc==null){
throw new NullPointerException("空指標例外!");
}
else if(index>=arc.length||index<0)
{
throw new ArrayIndexOutOfBoundsException("下標超出陣列的范圍!");
}
return arc[index];
}
}

3.Objects 非空判斷
import java.util.Objects;
public class Main{
public static void main(String[] args) {
int arc[]=null;
Objects.requireNonNull(arc,"空指標例外");
}
}
4.例外處理的第一種方法 throws關鍵字

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.module.FindException;
public class Main {
public static void main(String[] args) throws Exception {
//判斷路徑是否是C:\\.txt
Filename("C:\\.tx");
}
private static void Filename(String s) throws Exception {
//FileNotFoundException extends IOException extends Exception
if(!s.equals("C:\\.txt")){
throw new FileNotFoundException("該路徑不是C:\\.txt");
}
if(!s.endsWith(".txt"))
throw new IOException("檔案后綴不是.txt");
}
}
5.例外處理的第二種方法
try...catch()

import java.lang.invoke.MethodHandles;
public class Main{
public static void main(String[] args) {
int[] arc=new int[3];
try {
int getelem = getelem(arc, 3);
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("程式由catch處理");
}
System.out.println("后續代碼");
//如果拋出throws 程式交給JVM處理 程式遇到例外就會中斷
}
private static int getelem(int arc[],int index) throws ArrayIndexOutOfBoundsException{
if(index<0||index>=arc.length)
{
throw new ArrayIndexOutOfBoundsException("下標超出陣列的長度范圍");
}
return arc[index];
}
}
列印結果:
程式由catch處理
后續代碼
6.Throwable類中常用的方法

import java.lang.invoke.MethodHandles;
public class Main{
public static void main(String[] args) {
int[] arc=new int[3];
try {
int getelem = getelem(arc, 3);
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e.getMessage());
System.out.println(e.toString());
System.out.println(e);
e.printStackTrace();
}
System.out.println("后續代碼");
//如果拋出throws 程式交給JVM處理 程式遇到例外就會中斷
}
private static int getelem(int arc[],int index) throws ArrayIndexOutOfBoundsException{
if(index<0||index>=arc.length)
{
throw new ArrayIndexOutOfBoundsException("下標超出陣列的長度范圍");
}
return arc[index];
}
}
列印結果:
下標超出陣列的長度范圍
java.lang.ArrayIndexOutOfBoundsException: 下標超出陣列的長度范圍
java.lang.ArrayIndexOutOfBoundsException: 下標超出陣列的長度范圍
后續代碼
java.lang.ArrayIndexOutOfBoundsException: 下標超出陣列的長度范圍
at Main.getelem(Main.java:24)
at Main.main(Main.java:7)
7.例外處理的注意事項
(1)多個例外物件
import java.util.List;
/*
* 例外處理:多個例外物件的處理
* 1、多個例外分別處理
* 2、多個例外一次捕獲,多次處理
* 3、多個例外一次捕獲一次處理
* */
public class Main{
public static void main(String[] args) {
//int []arc=new int[3];
//System.out.println(arc[3]);//ArrayIndexOutOfBoundsException 3
//List<Integer> list = List.of(4, 3, 26, 6);
//System.out.println(list.get(4));//IndexOutOfBoundsException
/*1.多個例外分別處理
try{
int []arc=new int[3];
System.out.println(arc[3]);
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
}
try{
List<Integer> list = List.of(4, 3, 26, 6);
System.out.println(list.get(4));
}catch(IndexOutOfBoundsException e)
{
System.out.println(e);
}
java.lang.ArrayIndexOutOfBoundsException: 3
java.lang.IndexOutOfBoundsException: Index 4 out-of-bounds for length 4
*/
/*
2.多個例外一次捕獲多次處理
注意事項 子類物件必須寫在父類物件之上
try{
int []arc=new int[3];
System.out.println(arc[3]);
List<Integer> list = List.of(4, 3, 26, 6);
System.out.println(list.get(4));
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
catch (IndexOutOfBoundsException e)
{
System.out.println(e);
}
}
*/
/*
3、多個例外一次捕獲一次處理
try{
int []arc=new int[3];
System.out.println(arc[3]);
List<Integer> list = List.of(4, 3, 26, 6);
System.out.println(list.get(4));
}
catch(Exception e)
{
System.out.println(e);
}
}
*/
}
}
(2)finally代碼塊里有return陳述句
public class Main{
public static void main(String[] args) {
int method = method();
System.out.println(method);//20
}
private static int method() {
try{
int a[]=null;
int sum=0;
return sum;
}catch(NullPointerException e)
{
System.out.println(e);
}
finally {
int sum=20;
return sum;
}
}
}
(3)子父類例外

public class FU {
public void show1() throws NullPointerException, ClassCastException { }
public void show2() throws IndexOutOfBoundsException { };
public void show3() throws IndexOutOfBoundsException { };
public void show4() { }
}
class ZI extends FU{
@Override
public void show1() throws NullPointerException, ClassCastException { }
public void show2() throws ArrayIndexOutOfBoundsException{}
@Override
public void show3(){}
public void show4(){
try {
throw new Exception("編譯器例外");
} catch (Exception e) {
e.printStackTrace();
}
}
}
(4)自定義例外類


public class ReadException extends Exception{
public ReadException() {
}
public ReadException(String message) {//添加一個帶例外資訊的構造方法
super(message);
}
}
(5)自定義例外的小練習
注冊名稱
public class RegisterException extends Exception {
public RegisterException(String message) {
super(message);
}
public RegisterException() {
}
}
1)通過throws方法處理例外
import java.util.Scanner;
public class Register {
public static String []name={"Mary","Lisa","Jennie","JK","Minnie"};//全域變數
public static void main(String[] args) throws RegisterException {
System.out.println("請輸入您要注冊的姓名:");
Scanner input=new Scanner(System.in);
String usename=input.next();
Checkname(usename);
}
public static void Checkname(String usename) throws RegisterException {
for (String s : name) {
if(s.equals(usename))//true
{
throw new RegisterException("對不起,您的名字已經被注冊過!");
}
}
System.out.println("恭喜您,注冊成功!");
}
}
請輸入您要注冊的姓名:
jhfshdbfbsfhe
恭喜您,注冊成功!
請輸入您要注冊的姓名:
Mary
Exception in thread "main" RegisterException: 對不起,您的名字已經被注冊過!
at Register.Checkname(Register.java:16)
at Register.main(Register.java:9)
2)try...catch()處理
import java.util.Scanner;
public class Register {
public static String []name={"Mary","Lisa","Jennie","JK","Minnie"};//全域變數
public static void main(String[] args) {
System.out.println("請輸入您要注冊的姓名:");
Scanner input=new Scanner(System.in);
String usename=input.next();
Checkname(usename);
}
public static void Checkname(String usename){
for (String s : name) {
if(s.equals(usename))//true
{
try {
throw new RegisterException("對不起,您的名字已經被注冊過!");
} catch (RegisterException e) {
e.printStackTrace();
return;
}
}
}
System.out.println("恭喜您,注冊成功!");
}
}
3)也可以將RegisterException 繼承RuntimeException
public class RegisterException extends RuntimeException {
public RegisterException(String message) {
super(message);
}
public RegisterException() {
}
}
import java.util.Scanner;
public class Register {
public static String []name={"Mary","Lisa","Jennie","JK","Minnie"};//全域變數
public static void main(String[] args) {
System.out.println("請輸入您要注冊的姓名:");
Scanner input=new Scanner(System.in);
String usename=input.next();
Checkname(usename);
}
public static void Checkname(String usename){
for (String s : name) {
if(s.equals(usename))//true
{
throw new RegisterException("對不起,您的名字已經被注冊過!");
}
}
System.out.println("恭喜您,注冊成功!");
}
}
2.執行緒
1.0 并發和并行

2.行程與執行緒

執行緒的概念以及對執行緒的分析

3.執行緒的調度

4.主執行緒

5.創建多執行緒程式
第一種創建方式

public class Mythread extends Thread {
@Override
public void run() {
for(int i=0;i<5;i++)
{
System.out.println("run:"+i);
}
}
}
public class Main{
public static void main(String[] args) {
Mythread mt=new Mythread();
mt.start();
for(int i=0;i<5;i++)
{
System.out.println("Main:"+i);
}
}
}
第一次列印結果:
Main:0
Main:1
run:0
Main:2
Main:3
run:1
Main:4
run:2
run:3
run:4
第二次列印結果:
Main:0
run:0
Main:1
run:1
Main:2
run:2
Main:3
run:3
Main:4
run:4
每次列印結果可能不同 因為多個執行緒并發 搶占式調度
兩個執行緒 一個main執行緒 一個新執行緒 搶奪CPU(執行時間)
第二種方式

public class RunnableImpl implements Runnable{
@Override
public void run() {
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
public class Main{
public static void main(String[] args) {
RunnableImpl impl=new RunnableImpl();
Thread t=new Thread(impl);
t.start();
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
列印結果:
main--->0
main--->1
Thread-0--->0
main--->2
Thread-0--->1
Thread-0--->2
main--->3
Thread-0--->3
main--->4
Thread-0--->4
實作Runnable介面創建多執行緒程式的好處

6.Thread類常用方法
(1)獲取執行緒名稱

(2) 設定執行緒的名稱

public class Mythread extends Thread {
public Mythread(String name) {
super(name);
}
public Mythread() {
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Main{
public static void main(String[] args) {
Mythread mt=new Mythread();
mt.setName("START");//START
mt.start();
new Mythread("Hello").start();//Hello
}
}
(3)sleep方法

一秒列印一個數
public class Main{
public static void main(String[] args) {
for (int i = 1; i <=10 ; i++) {
System.out.println(i);
try{
Thread.sleep(1000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
7.匿名內部類方式實作執行緒的創建

public class Main{
public static void main(String[] args) {
/*第一種創建方式
new Thread(){
@Override
public void run() {
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+"->"+i);
}
}
}.start();
*/
/*第二種通過Runnable介面
(1)
Runnable r=new Runnable() {
@Override
public void run() {
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+"->"+i);
}
}
};
new Thread(r).start();
(2)簡化版本
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+"->"+i);
}
}
}).start();
*/
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+"->"+i);
}
}
}
3.執行緒安全問題
1.0 概述

2.執行緒安全問題產生
public class RunnableImpl implements Runnable{
private int ticket=100;
@Override
public void run() {
while(true)
{
if(ticket>0)
{
try{
Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"張票");
ticket--;
}
}
}
}
public class Main{
public static void main(String[] args) {
RunnableImpl r=new RunnableImpl();
Thread r1=new Thread(r);
Thread r2=new Thread(r);
Thread r3=new Thread(r);
r1.start();
r2.start();
r3.start();
}
}

結果中出現 1 0 -1 不存在的票說明 在共享資料的同時發生了安全性問題
3.解決執行緒安全問題
(1)第一種方式 同步代碼塊

public class RunnableImpl implements Runnable{
private int ticket=100;
Object obj=new Object() ;
@Override
public void run() {
while(true)
{
synchronized (obj)
{
if(ticket>0)
{
try{
Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"張票");
ticket--;
}
}
}
}
}
同步技術的原理

(2)第二種方法 同步方法


public class RunnableImpl implements Runnable{
private int ticket=100;
@Override
public void run() {
while(true)
{
payticket();
}
}
public synchronized void payticket()
{
if(ticket>0)
{
try{
Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"張票");
ticket--;
}
}
}
------靜態同步方法

(3)第三種方式 Lock鎖

寫法一:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class RunnableImpl implements Runnable{
private int ticket=100;
Lock l=new ReentrantLock();
@Override
public void run() {
while (true)
{
l.lock();
if(ticket>0)
{
try{
Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"張票");
ticket--;
}
l.unlock();
}
}
}
寫法二(效率高)
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class RunnableImpl implements Runnable{
private int ticket=100;
Lock l=new ReentrantLock();
@Override
public void run() {
while (true)
{
l.lock();
if(ticket>0)
{
try{
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"正在售出第"+ticket+"張票");
ticket--;
}catch(Exception e)
{
e.printStackTrace();
}finally {
l.unlock();
}
}
}
}
}
4.執行緒狀態
1.0 概述

2.0等待喚醒案例
分析賣包子案例

代碼實作

public class Sale {
public static void main(String[] args) {
Object obj=new Object();//鎖物件
//顧客
new Thread() {
@Override
public void run() {
synchronized (obj)
{
System.out.println("顧客告訴老板自己的需求");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("美味的包子已經做好,開吃!");
}
}.start();
//老板
new Thread(){
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj)
{
System.out.println("老板5秒做好了包子");
obj.notify();
}
}
}.start();
}
}
列印結果:
顧客告訴老板自己的需求
老板5秒做好了包子
美味的包子已經做好,開吃!
Object類中 wait帶參方法以及notify方法


3.等待喚醒機制
案例
public class Baozi {
String Pi;
String Xian;
boolean falg=false;
}
public class Baozipu extends Thread {
private Baozi baozi;
public Baozipu( Baozi baozi) {
this.baozi = baozi;
}
@Override
public void run() {
int count=0;
while(true)
{
synchronized (baozi)
{
//包子狀態 有
if(baozi.falg==true)
{
try {
baozi.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//生產包子
if(count%2==0)
{
baozi.Pi="薄皮";
baozi.Xian="豬肉玉米";
}
else
{
baozi.Pi="涼皮";
baozi.Xian="牛肉三鮮";
}
count++;
System.out.println("正在做"+baozi.Pi+baozi.Xian+"的包子");
try {
Thread.sleep(5000);//5秒生產
} catch (InterruptedException e) {
e.printStackTrace();
}
baozi.falg=true;
baozi.notify();
System.out.println(baozi.Pi+baozi.Xian+"的包子已經做好 開吃!");
}
}
}
}

public class Chihuo extends Thread {
private Baozi baozi;
public Chihuo(Baozi baozi) {
this.baozi = baozi;
}
@Override
public void run() {
while(true)
{
synchronized (baozi)
{
if(baozi.falg==false)
{
try {
baozi.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//喚醒后
System.out.println("吃貨正在吃:"+baozi.Pi+baozi.Xian+"的包子");
baozi.falg=false;
baozi.notify();
System.out.println("吃貨已經吃完,繼續生產");
System.out.println("----------------------");
}
}
}
}
測驗類(顧客)
public class Main{
public static void main(String[] args) {
Baozi bz=new Baozi();
new Baozipu(bz).start();
new Chihuo(bz).start();
}
}
5.執行緒池

public class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在執行");
}
}
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main{
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(new RunnableImpl());//pool-1-thread-1正在執行
pool.submit(new RunnableImpl());//pool-1-thread-2正在執行
//只有兩個執行緒 執行緒池會一直開啟 一個執行緒結束后歸還 可以繼續使用
pool.submit(new RunnableImpl());//pool-1-thread-1正在執行
pool.shutdown();//銷毀執行緒池
}
}
6.函式式編程思想
1.0 概述

2.0體驗Lambda的更優

public class Main{
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在執行");
}
}.start();
System.out.println("----------");
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "正在執行");
}).start();
}
}
列印結果:
----------
Thread-1正在執行
Thread-0正在執行
3.0 Lambda標準格式
(1)無引數無回傳值

public interface Cook {
public abstract void makefood();
}
public class Main{
public static void main(String[] args) {
show(()->{
System.out.println("吃飯啦!德善");
}
);
}
public static void show(Cook cook) {
cook.makefood();
}
}
列印結果:
吃飯啦!德善
(2)有引數有回傳值
對年齡進行排序
import java.util.Arrays;
import java.util.Comparator;
public class Main{
public static void main(String[] args) {
Person[] person = {new Person("V", 25),
new Person("JK", 23),
new Person("Jin", 27)};
/*
Arrays.sort(person, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();//升序
}
});
*/
Arrays.sort(person,(Person o1, Person o2) ->
{
return o1.getAge()-o2.getAge();
});
for (Person person1 : person) {
System.out.println(person1.getName()+" "+person1.getAge());
}
}
}
列印結果:
JK 23
V 25
Jin 27
4.0 lambda可省略


轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/161009.html
標籤:Java
