• JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)


    1.throws和throw的区别

    throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常

    使用方法

    public int method(int[] arr) throws NullPointerException{}

    public int method(int[] arr){

    if(arr==null){

    throw new NullPointerException (“数组的引用不能为空”);

    }

    }

    throws 抛出的是异常类,可以抛出多个,用逗号隔开,throw抛出的是异常对象

    2.Java中的四种权限

    public protected default private,其中如果什么都没有写,就是default

    3.多线程

    多线程的好处:解决了多个程序同时运行的问题。

    多线程的弊端:线程太多会导致效率降低

    其实应用程序的执行都是CPU在做着快速的切换完成的。这个切换是随机的

    java中运行垃圾回收是:System.gc();

            

    创建线程方式一并使用

    代码如下:

    package com.itcast.test;
    
    /**
     * 创建线程方式
     * 1.子类继承Thread类,子类覆盖父类中的run方法,将线程要执行的代码写在run方法中
     * 2.建立子类对象的同时线程也被创建
     * 3.通过调用start方法开启线程
     * @author yxl
     * 
     */
    public class ThreadSub extends Thread {
        @Override
        public void run() {
            // 这里面是线程要执行的代码
            for (int i = 0; i < 10; i++) {
                System.out.println(i+"---"+Thread.currentThread().getName());
            }
        }
        public ThreadSub(String threadName){
        }
    }
    package com.itcast.test;
    public class Demo {
    
        public static void main(String[] args) {
            //创建线程并调用第一种方式
            ThreadSub threadSub = new ThreadSub("线程1");
            ThreadSub threadSub2 = new ThreadSub("线程2");
            threadSub.start();// 开启线程,调用run方法
                                // threadSub.run();如果直接调用run()方法就是只调用主线程执行
            threadSub2.start();
            
        }
    
    }

    创建线程方式二推荐使用这种方式

    代码如下:

    package com.itcast.test;
    /**
     * 创建线程的第二种方式,实现Runnable接口。推荐使用这种方式
     * 1.定义类实现Runnable接口
     * 2.覆盖接口中的run方法,并将线程的任务代码封装到run方法中
     * 3.通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数
     * 的参数进行传递,通过对象调用run方法
     * 4.调用线程对象的start()开启线程
     * @author yxl
     *
     */
    public class ImplementThread implements Runnable {
    
        @Override
        public void run() {
            // 这里面是线程要执行的代码
            for (int i = 0; i < 10; i++) {
                System.out.println(i+"---"+Thread.currentThread().getName());
            }
    
        }
    
    }
    package com.itcast.test;
    public class Demo {
    
        public static void main(String[] args) {
            //创建线程并调用第二种方式,推荐使用第二种方式
            ImplementThread thread = new ImplementThread();
            Thread t =new Thread(thread);
            t.start();
            Thread t2 =new Thread(thread);
            t2.start();
            
        }
    
    }

    同步解决线程安全问题(JDK1.5之前版本使用的方式)

    Object object = new Object();

    synchronized (object) {

                               

    }

    相当于lock锁

    /**

    * 同步函数

    * 同步函数使用的锁是this,建议使用同步代码块锁

    */

    public synchronized void Show() {

                      

    }

    线程间通讯:

    多个线程在处理同一资源,但是任务却不同。

    生产者消费者模式:

    代码如下:      

    package com.itcast.test1;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /*
     * 等待唤醒机制
     * 1.wait():让线程处于冻结状态,被wait的线程会被存储到线程池中
     * 2.notify():唤醒线程池中一个线程(任意)
     * 3.notifyAll():唤醒线程池中的所有线程。
     * 这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法,必须要明确到底操作的是哪个锁上的线程。
     * 以上方法都是定义在Object类中,因为这些方法是监视器的方法,监视器其实就是锁
     * jdk1.5以后将同步和锁封装成了对象,并将操作锁的隐士动作变成了显示动作 。
     * Lock接口:出现替代了同步代码块或者同步函数。将同步的隐士锁操作变成现实锁操作,同时更为灵活,可以一个锁上加上多组监视器
     * lock():获取锁,unlock():释放锁,通常需要定义在finally代码块中。
     * Condition接口:出现替代了Object中的wait notify notifyAll方法,将这些监视器方法单独进行了封装,
     * 变成Condition监视器对象。可以任意锁进行组合。
     * await()
     * signal()
     * signalAll()
     */
    /**
     * 生产资源类 
     * @author yxl
     *
     */
    public class Resourse {
        private String name;
        public boolean flag = false;// 用来标识用的,为了实现生产一个,消费一个,为true,表示生产者有数据
        Lock lock = new ReentrantLock();
        Condition conditionProductor = lock.newCondition();
        Condition conditionCustomer = lock.newCondition();
        int count = 0;
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void set(String name) {
            lock.lock();
            try {
                while (flag) {
                    conditionProductor.await();
                }
                setName(name+count);
                count++;
                System.out.println(Thread.currentThread().getName()+"-----"+getName());
                flag = true;
                conditionCustomer.signal();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
        
        public void out(){
            lock.lock();
            try {
                while (!flag) {
                    conditionCustomer.await();
                }
                System.out.println(Thread.currentThread().getName()+"-----"+name);
                flag = false;
                conditionProductor.signal();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    package com.itcast.test1;
    /**
     * 生产者类
     * @author yxl
     *
     */
    public class Productor implements Runnable {
        Resourse resourse ;
        public Productor(Resourse resourse){
            this.resourse = resourse;
        }
        @Override
        public void run() {
            while(true){
            resourse.set("生产者名称");
            }
        }
    }
    package com.itcast.test1;
    /**
     * 消费者类
     * @author yxl
     *
     */
    public class Customer implements Runnable {
        Resourse resourse ;
        public Customer(Resourse resourse){
            this.resourse = resourse;
        }
        @Override
        public void run() {
            while(true){
            resourse.out();
            }
        }
    }
    package com.itcast.test1;
    
    public class MainDemo {
    
        public static void main(String[] args) {
            Resourse resourse = new Resourse();
            Productor productor = new Productor(resourse);
            Customer customer = new Customer(resourse);
            Thread thread1 = new Thread(productor);
            thread1.start();
            Thread thread2 = new Thread(customer);
            thread2.start();
            Thread thread3 = new Thread(productor);
            thread3.start();
            Thread thread4 = new Thread(customer);
            thread4.start();
        }
    
    }

    wait和sleep的区别:

    1.wait可以指定时间也可以不指定,sleep必须指定时间

    2.在同步中,对CPU的执行权和锁的处理方式不同

    wait释放执行权,释放锁,sleep释放执行权,不释放锁,因为它一定有时间的限制,不需要释放锁。

    终止线程的方法:

    1.可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态中来,让线程具备CUP的执行资格。当然强制动作会发生InterruptedException,记得要处理,在异常处理中使用标记来终止线程

    2.也可以使用thread2.setDaemon(true);将线程设置为守护线程,也就是后台线程,所有前台线程都结束,后台线程自动结束

    代码如下:

    package com.itcast.test2;
    
    public class StopThread implements Runnable {
        private boolean flag = true;
        @Override
        public synchronized void run() {
            while(flag){
                try {
                    wait();
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName());
                    //出错的时候,可以设置标记
                    flag = false;
                    
                }
                System.out.println(Thread.currentThread().getName());
            }
        }
    }
    package com.itcast.test2;
    
    public class MainDemo {
    
        public static void main(String[] args) {
            StopThread stopThread = new StopThread();
            Thread thread = new Thread(stopThread);
            thread.start();
            thread.setPriority(Thread.MAX_PRIORITY);//设置线程的优先级,值为1-10
            Thread thread1 = new Thread(stopThread);
            thread1.start();
            Thread thread2 = new Thread(stopThread);
            thread2.setDaemon(true);//第二种终止线程的方法,将线程设置为守护线程,也就是后台线程
                                    //所有前台线程都结束,后台线程自动结束
            thread2.start();
            for (int i = 0; i < 100; i++) {
                if (i==58) {
                    thread.interrupt();//调用interrupt()方法终止线程
                    thread1.interrupt();
                }
                System.out.println(i);
            }
        }
    }
  • 相关阅读:
    工厂模式
    装饰器模式
    策略模式
    代理模式
    建造者模式
    单例模式
    观察者模式
    JVM运行时数据区
    Export to excel
    C#网络编程(同步传输字符串) Part.2 [转自JimmyZhang博客]
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/3512867.html
Copyright © 2020-2023  润新知