异常与多线程


Exception:
Error:异常产生过程解析异常的处理   throw 声明异常:throws
2.4捕获异常 try...catch     快捷键:Ctrl+Alt+t
处理异常的方法
finally代码块:

import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int num=0;
        String input ="";

        while(true)
        {
            System.out.println("请输入一个整数: ");
            input =sc.next();
            try {
                num=Integer.parseInt(input);//这里有可能抛出异常
                break;
            } catch (NumberFormatException e) {
                System.out.println("你输入的不是一个整数");
            }
        }
        System.out.println("你输入的值是: "+num);
    }
}

异常注意事项:
 

import java.util.Scanner;
public class exception {
    static String[] usernames = {"张三", "李四", "王五"};

    public static void main(String[] args) throws RegisterException {
        //使用Scanner获取用户输入的注册的用户名(前端,页面)
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您注册的用户名: ");
        String username = sc.next();
        checkUsername(username);
    }

    //定义一个方法,对用户输入的注册用户名进行决断
    public static void checkUsername(String username) throws RegisterException {
        for (int i = 0; i < usernames.length; i++) {
            if (username.equals(usernames[i])) {
                //用户名已经存在,抛出registerException异常
                throw new RegisterException("亲,该用户名已经被注册");
            }
        }
        System.out.println("恭喜您!注册成功");
    }
}

多线程 !  线程与进程

 
Thread类:

获取当前线程的名称:                                   设置线程的名称(了解):

sleep(本身有异常)

创建多线程程序的第二种方式:实现Runnable接口 
1.4Thread和Runnable的区别

1.5匿名内部类方式实现线程的创建
 

    public static void main(String[] args) {
        t1 t1 = new t1();
        t2 t2 = new t2();

        Thread T1 = new Thread(t1);
        Thread T2 = new Thread(t2);
        T1.start();
        T2.start();
    }
}

class t1 implements Runnable {
    int count = 0;
    @Override
    public void run() {
        while (true) {
            System.out.println("Hello " + (++count));
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (count == 10)
                break;
        }
    }
}

class t2 implements Runnable {
    int count = 0;

    @Override
    public void run() {
        while (true) {
            System.out.println("Hi " + (++count));
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 5)
                break;
        }
    }
}

线程常用方法


yield(根据 内核态 资源是否紧张 决定的)在 资源紧张的时候 礼让成功的概率更大 

import static java.lang.Thread.sleep;
public class Main {
    public static void main(String[] args) throws InterruptedException {

        T t = new T();
        Thread Thread1 = new Thread(t);
        for (int i = 1; i <= 10; i++) {
            System.out.println("Hi" + i);
            if (i == 5) {
                Thread1.start();
                Thread1.join();
            }
        }
        System.out.println("主线程结束");
    }
}
class T implements Runnable {
    private int count = 0;

    @Override
    public void run() {
        while (true) {
            System.out.println("Hello " + (++count));
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 10) {
                //System.out.println("子线程结束");
                break;
            }
        }
    }

}

第二章  线程安全 (多线程访问共享数据)

 2.2解决线程安全问题

 

import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws exception {
        ThreadA a = new ThreadA();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(a);
        t1.start();
        t2.start();
    }
}
class ThreadA extends Thread {
    private boolean flag = true;
    private int amount = 10000;
    public synchronized void get() {
        if (amount <= 1000) {
            System.out.println("余额不足1000元");
            flag = false;
            return;
        }
        System.out.println(Thread.currentThread().getName() + "取钱,余额:"
                + (amount -= 1000));

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        while (flag) {
            get();
        }
    }
}

为啥synchronized建议用Runnable而不是继承Thread???

 线程的死锁

public class Main {
    public static void main(String[] args) {
        //模拟 死锁现象
        deadLock A = new deadLock(true);
        A.start();
        deadLock B = new deadLock(false);
        B.start();
    }
}

class deadLock extends Thread {
    static Object o1 = new Object();//多线程使用static 共享一个对象
    static Object o2 = new Object();
    boolean flag;

    public deadLock(boolean flag) {//构造器
        this.flag = flag;
    }

    @Override
    public void run() {
        //下面业务逻辑的分析:
        //1. if(flag)=T, 线程A就会得到o1对象锁,然后尝试获取o2对象锁
        //2.如果线程A得不到o2对象锁,就会Blocked阻塞
        //3. if(flag)=F, 线程B就会得到o2对象锁,然后尝试获取o1对象锁
        //4.如果线程B得不到o1对象锁,就会Blocked
        //5.此业务 极有可能 阻塞 死锁
        if (flag) {
            synchronized (o1) {//对象互斥锁,下面就是同步代码
                System.out.println(Thread.currentThread().getName() + "进入1");
                synchronized (o2) {//获得l1对象的监事权
                    System.out.println(Thread.currentThread().getName() + 
"进入2");
                }
            }
        } else {
            synchronized (o2) {
                System.out.println(Thread.currentThread().getName() + 
"进入3");
                synchronized (o1) {//获得l3对象的监事权
                    System.out.println(Thread.currentThread().getName() +
 "进入4");
                }
            }

        }

    }
}
import static java.lang.Thread.sleep;

public class Main {
    public static void main(String[] args) throws InterruptedException {

        T t = new T();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }
}

//使用synchronized实现线程同步
class T implements Runnable {
    private int count = 50;
    private boolean loop = true;

    public synchronized void sell() {//同步方法 同一时刻 只有一个线程执行
        if (count <= 0) {
            System.out.println("售票结束...");
            loop=false;
            return;
        }
        try {
            sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("窗口" + Thread.currentThread().getName() +
                "售出一张票,剩余" + (--count) + "张票");
    }
    @Override
    public void run() {
        while (loop) {
            sell();
        }
    }

}

线程终止 

//启动一个线程t,要求在main线程中 停止线程t
public class Main {
    public static void main(String[] args) throws InterruptedException {

        T t = new T();
        t.start();
        //希望main线程去控制t1的终止,必须可以修改loop
        //t退出 run 方法,聪儿终止t线程->通知方式

        //主线程休眠5秒,再通知 t1线程退出
        System.out.println("主线程休眠");
        Thread.sleep(5 * 1000);
        t.setLoop(false);
    }
}

class T extends Thread {
    private static int count = 0;
    //设置 控制变量
    private boolean loop = true;

    @Override
    public void run() {
        while (loop) {

            try {
                sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程运行===" + (++count));
        }
    }
    public void setLoop(boolean b) {
        this.loop = b;
    }
}

用户线程和 守护线程   在主方法里setDaemon(true);


import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        ThreadA A = new ThreadA();
        ThreadB B = new ThreadB(A);
        A.start();
        B.start();
    }
}

class ThreadA extends Thread {
    boolean flag = true;

    public void setflag(boolean flag) {//构造器
        this.flag = flag;
    }

    @Override
    public void run() {
        while (flag) {
            System.out.println((int) (Math.random() * 100 + 1));
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class ThreadB extends Thread {
    private Scanner sc = new Scanner(System.in);
    private ThreadA a;

    public ThreadB(ThreadA a) {
        this.a = a;
    }
    @Override
    public void run() {
        while (true) {
            System.out.println("请输入你的指令");
            char n = sc.next().toUpperCase().charAt(0);
            if (n == 'Q') {
                a.setflag(false);
                System.out.println("B线程退出");
                break;
            }
        }
    }
}

2.5Lock锁
  

  线程状态                                                                           Waiting(无限等待):
 

public class WaitAndNotify {
    public static void main(String[] args) {
        //创建锁对象,保证唯一
        Object obj = new Object();
        //创建一个顾客线程(消费者)
        new Thread() {
            @Override
            public void run() {
                //保证等待和唤醒的线程只能有一个执行,需要使用同步技术
                synchronized (obj) {
                    System.out.println("告知老板要的包子种类和数量");
                    //调用wait方法,放弃cpu的执行,进入到WAITING状态(无限等待)
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //唤醒之后执行的代码
                    System.out.println("包子已经做好了,开吃");
                }
            }
        }.start();

        //创建一个老板线程(生产者)
        new Thread() {
            @Override
            public void run() {
                //花了5秒做包子
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //保证等待和唤醒的线程只能有一个执行,需要使用同步技术
                synchronized (obj) {
                    System.out.println("老板5秒之后做好包子,告知顾客");
                    //调用wait方法,放弃cpu的执行,进入到WAITING状态(无限等待)
                    obj.notify();
                }
            }
        }.start();
    }
}

线程间通信
 
 等待唤醒机制
线程池

posted @ 2022-07-15 23:05  软工菜鸡  阅读(3)  评论(0编辑  收藏  举报  来源