zoukankan      html  css  js  c++  java
  • Java学习笔记

    生产者&消费者模型

    • wait & notify 方法不是线程对象的方法,是普通java对象的都有的方法

    • wait & notify方法建立在线程同步的基础之上。因为多线程要同时操作一个对象,有线程安全问题

    • wait(): o.wait()让正在o对象上活动的线程t进入等待状态,并且释放掉之前占有对象o的锁

    • notify(): o.notify()让正在o对象上等待的线程唤醒,只是通知,不会释放掉之前占有对象o的锁

    示例程序:

    public class ProducerAndConsumer {
        public static void main(String[] args) {
            List list = new ArrayList();
    
            Producer pro = new Producer(list);
            Consumer con = new Consumer(list);
    
            pro.setName("生产者进程");
            con.setName("消费者进程");
    
            pro.start();
            con.start();
        }
    
    }
    
    //生产者线程类
    class Producer extends Thread{
        private List list;
    
        public Producer(List list){
            this.list = list;
        }
        @Override
        public void run() {
            //一直生产
            while (true){
                synchronized (list){
                    if(list.size() > 0){
                        try {
                            //当前线程进入等待状态,并且释放Producer之前占有的list的锁
                            list.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //程序能执行到这里说明仓库是空的,可以生产
                    Object obj = new Object();
                    list.add(obj);
                    System.out.println(Thread.currentThread().getName() + "-->" + obj);
                    //唤醒消费者进行消费:唤醒list对象上正在等待的线程,但不会释放之前占有的list的锁
                    list.notify();
                }
            }
        }
    }
    
    //消费者线程类
    class Consumer extends Thread{
        private List list;
    
        public Consumer(List list){
            this.list = list;
        }
    
        @Override
        public void run() {
            while (true){
                synchronized (list){
                    if(list.size() == 0){
                        try {
                            list.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //程序能执行到这里说明仓库是满的,可以消费
                    Object obj = list.remove(0);
                    System.out.println(Thread.currentThread().getName() + "-->" + obj);
    
                    //唤醒生产者进行生产:唤醒list对象上正在等待的线程,但不会释放之前占有的list的锁
                    list.notify();
                }
            }
        }
    }
    

    守护线程

    • 守护线程:后台线程,例如垃圾回收线程
    • 特点:一般守护线程是一个死循环,所有的用户线程只要结束,守护线程自动结束
    • 方法:final void setDaemon(boolean on) true表示设置调用线程为守护线程

    示例程序:

    public class ProtectedThreadTest {
        public static void main(String[] args) {
            BakDataThread bdt = new BakDataThread();
    
            //设置线程为守护线程,所有的用户线程都结束,守护线程会自动结束
            bdt.setDaemon(true);
    
            bdt.start();
            
            for (int i = 0; i < 5; i++) {
                System.out.println("主线程运行  ---》》" + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class BakDataThread extends Thread{
        @Override
        //方法覆盖不能比之前的方法抛出更多的异常,所以只能采用try catch的处理方式
        public void run() {
            int i = 0;
            while (true){
                System.out.println("守护线程运行---》》" + i++);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    定时器

    • 作用:间隔特定的时间,执行特定的程序
    • 在java的类库中已经写好了一个定时器:java.util.Timer

    实现步骤

    • 1.创建定时器 public Timer(boolean isDaemon)
    • 2.调用schedule方法:void schedule(TimerTask task, Date firstTime, long period)
      参数:抽象类TimerTask; 第一次的执行时刻; 执行间隔时间/毫秒

    示例代码

    public class TimerTest {
        public static void main(String[] args) throws ParseException {
            //创建定时器
            Timer timer = new Timer();
            //Timer timer = new Timer(true);   //true:表示作为一个守护线程运行
    
            //指定起始执行时刻
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date firstTime = sdf.parse("2020-05-31 13:08:10");
            
            //第一种方式:使用匿名内部类的方式,实现抽象类TimerTask
            //从firstTime开始,每period毫秒执行一次run()方法
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String strTime = sdf.format(new Date());
                    System.out.println(strTime + " : 完成了一次数据备份");
                }
            },firstTime,1000 * 10);
        }
    }
    
    // 第二种方法:编写定时任务类,实现抽象类TimerTask
    class LogTimerTask extends TimerTask {
        @Override
        public void run() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String strTime = sdf.format(new Date());
            System.out.println(strTime + " : 完成了一次数据备份");
        }
    }
    
  • 相关阅读:
    PHP的函数应用
    MyEclipse 使用Junit
    JAVASE知识点总结
    常见排序算法
    数据结构的java实现
    JDK1.5新特性总结
    Oracle练习题
    Oracle面试题2
    Oracle面试题1
    分别使用Statement和PreparedStatement对数据库进行操作
  • 原文地址:https://www.cnblogs.com/zy200128/p/13030413.html
Copyright © 2011-2022 走看看