目录

一.等待唤醒机制

二.线程池 

三.Timer定时器


一.等待唤醒机制

  • 等待唤醒机制

这是多个线程间的一种协作机制。就好比在公司里你和你的同事们,你们可能存在在晋升时的竞争,但更多时候你们更多是一起合作以完成某些任务。

就是在一个线程进行了规定操作后,就进入无限等待状态(ait()),调用notfiy()方法唤醒其他线程来执行,其他线程执行完后,进入无限等待,唤醒等待线程执行,依次类推....  如果需要,可以使用 notifyAll()来唤醒所有的等待线程。

wait/notify 就是线程间的一种协作机制。

  • 待唤醒机制相关方法介绍
    • public void wait() : 让当前线程进入到等待状态 此方法必须锁对象调用.
    • public void notify(): 唤醒当前锁对象上等待状态的线程  此方法必须锁对象调用.
public class Test {
    public static Object obj = new Object();
    public static void main(String[] args) {
        /*
            等待唤醒机制相关方法介绍
                - public void wait() : 让当前线程进入到等待状态 此方法必须锁对象调用.
                - public void notify() : 唤醒当前锁对象上等待状态的线程  此方法必须锁对象调用.
         */


       // 线程1: 无限等待
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 任务代码
                synchronized (Test.obj) {
                    System.out.println("线程1:准备调用wait方法进入无限等待");
                    // 进入无限等待
                    try {
                        Test.obj.wait();// 释放锁,不会争夺cpu
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程1:被唤醒了...");
                }
            }
        }).start();
        // 线程2: 唤醒线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 任务代码
                synchronized (Test.obj){
                    System.out.println("线程2:准备调用notify方法唤醒等待线程");
                    Test.obj.notify();
                }
            }
        }).start();
    }
}

 

  • 等待唤醒案例

 

二.线程池 

创建线程每次都要和操作系统进行交互,线程执行完任务后就会销毁,如果频繁的大量去创建线程肯定会造成系统资源开销很大,降低程序的运行效率。

线程池思想就很好的解决了频繁创建线程的问题,我们可以预先创建好一些线程,把他们放在一个容器中,需要线程执行任务的时候,从容器中取出线程,任务执行完毕后将线程在放回容器。

 

  •  JDK线程池
    • java.util.concurrent 包中定义了线程池相关的类和接口。
  • Executors类
    • 创建线程池对象的工厂方法,使用此类可以创建线程池对象。

 

  • ExecutorService接口
    • 线程池对象的管理接口,提交线程任务,关闭线程池等功能。

 

  • Callable接口
    • 线程执行的任务接口,类似于Runnable接口。
    • 接口方法`public V call()throw Exception`
    • 线程要执行的任务方法
    • 比起run()方法,call()方法具有返回值,可以获取到线程执行的结果。
  • Future接口
    • 异步计算结果,就是线程执行完成后的结果。
    • 接口方法public V get()获取线程执行的结果,就是获取call()方法返回值。

 

/**
 * JDK1.5后,提供的线程池  juc包
 * java.util.concurrent.Executors类
 * Executors 是工厂类,创建对象,用来创建线程池对象
 * static ExecutorService newFixedThreadPool(int nThreads)
 * 创建线程池对象,传递参数是线程池中线程的个数,是个无界队列
 * 方法的返回值: ExecutorService接口,返回的是实现类对象
 * 接口就表示线程池对象
 * ExecutorService接口方法: 提交线程执行的任务
 *   submit(Runnable接口实现类)
 */
public class ThreadDemo {
    public static void main(String[] args) {
        //创建线程池对象,固定个数2个线程
        ExecutorService es =  Executors.newFixedThreadPool(2);
        //提交任务,submit方法(Runnable接口实现类)
        es.submit( new MyRunnable());
        es.submit( new MyRunnable());
        es.submit( new MyRunnable());
        es.shutdown();
    }
}

 

public class MyRunnable implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName()+ " 线程执行任务");
    }
}

 

 

/**
 * java.util.concurrent.Callable<V>接口
 *  V call() throws Exception;
 *  可以抛出异常,方法具有返回值
 *  接口只能在线程池中使用
 *  线程池对象 submit(  Callable接口 )提交线程任务
 *  方法的返回值是 Future接口,表示线程执行完毕后的返回值
 */
public class ThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //线程池,提交任务,获取线程执行后的返回值
        ExecutorService es =  Executors.newFixedThreadPool(2);
        //接受submit方法的返回值
        Future<String> future =  es.submit(new MyCallable());
        //接口中的方法 get()获取线程的返回值
        String str = future.get();
        System.out.println(str);
    }
}

 

public class MyCallable implements Callable<String> {
    public String call()throws Exception{
        System.out.println("线程开启");
        return "线程结果字符串";
    }
}

 

  • 实现线程池程序
    • 创建有2个线程的线程池,分别提交线程执行的任务,一个线程执行字符串切割,一个执行1+100的和。实现Callable接口,字符串切割功能:代码略 

三.Timer定时器

Java中的定时器,可以根据指定的时间来运行程序。

java.util.Timer一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。定时器是使用新建的线程来执行,这样即使主线程main结束了,定时器也依然会继续工作。

  • Timer类的方法
    • 构造方法:无参数。
    • 定时方法:public void schedule(TimerTask task,Date firstTime,long period)
    • TimerTask是定时器要执行的任务,一个抽象类,我们需要继承并重写方法run()
    • firstTime定时器开始执行的时间
    •  period时间间隔,毫秒值
      /**
       * 定时器: 在指定的时间隔内,进行操作
       * java.util.Timer 实现定时器
       * 构造方法直接new 无参数
       * 启动定时器方法:
       *                定时器任务         开始时间        毫秒间隔
       *   void schedule(TimerTask task, Date firstTime, long period)
       *   TimerTask参数,抽象类,传递子类对象,重写run()
       */
      public class TimerDemo {
          public static void main(String[] args) {
              Timer timer = new Timer();
              //开启定时器
              timer.schedule(new TimerTask(){
                  public void run(){
                      System.out.println("定时执行");
                  }
              }, new Date(),3000);
          }
      }
      /*class MyTask extends TimerTask{
          public void run(){
              System.out.println("定时执行");
          }
      }*/
      

 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐