黑马程序员_JAVA之多线程

来源:互联网 发布:淘宝店铺怎么改名 编辑:程序博客网 时间:2024/05/12 21:39
------- android培训、java培训、期待与您交流!----------


多线程:


一.基本概念:


线程:是依赖于进程的执行绪(执行路径/控制单元),是程序使用CPU的基本单位
进程:当前正在执行的程序,代表一个应用程序在内存中的执行区域.


多进程:同一时间段内执行多个任务.同一时刻只能执行一个任务.Windows为代表的操作系统.
多进程并不提高某个程序的执行速度,仅仅是提高了CPU的使用率.真正的多进程执行是指多核同时计算.


单线程:一个进程中,只有一个线程执行.
多线程:同一个进程中,多个线程执行.这多个线程共享该进程资源(堆内存与方法区),栈内存独立.即每一个线程占用一个栈
二.线程的相关概念:


基本概念
线程两种调度模型:
分时调度模型----所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片.
抢占式调度模型--优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)
Java使用的为抢占调度模型
线程并行与线程并发
线程并行:正常的多线程执行就是线程并行.即逻辑上同一时间同时运行
线程并发:由于线程抢占而不应出现的某一时刻的线程及相关数据状态.如并发修改异常的产生.
JVM的启动支持多线程:
JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的.
Java命令会启动java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程”,然后主线程去调用某个类的 main 方法,所以 main方法运行在主线程中


三. Thread:线程类
1)构造方法:


public Thread(Runnable target) 指定线程执行目标




2)实现多线程的方式


public void start()  开启线程


public final String getName()  获取线程名称


public final void setName(String name)  设置线程名称


public static Thread currentThread() 获取当前的线程




3)Runnable:线程执行目标    内含一个run方法,供线程执行。


方式一:


定义自己的线程类。该类继承了Thread类


重写run方法


run相当于这个线程当中的main方法


创建线程对象


调用线程的start方法开启线程






方式二:


定义自己的类(线程执行目标类),实现Runnable接口


创建线程执行目标类对象


使用线程执行目标对象创建线程对象


调用线程的start方法开启线程


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast;  
  
public class Demo {  
  
    public static void main(String[] args) {  
  
        method2();  
    }  
    //多线程创建方式一:  
    public static void method(){  
        MyThread mt = new MyThread("唐嫣");  
        //mt.setName("唐嫣");  
        MyThread mt2 = new MyThread("诗诗");  
        //mt2.setName("诗诗");  
//      如果直接调用run方法,就是调用了一个普通对象的普通方法,没有新线程  
//      mt.run();  
//      mt2.run();  
          
        //调用start方法开启线程  
        mt.start();  
        mt2.start();  
    }  
    //多线程创建方式二:  
    public static void method2() {  
        //创建线程执行目标类对象  
        MyRunnable mr = new MyRunnable();  
        //通过线程执行目标类对象创建线程对象  
        Thread thread = new Thread(mr,"唐嫣");  
        Thread thread2 = new Thread(mr,"诗诗");  
        Thread thread3 = new Thread(mr,"baby");  
        //开启线程  
        thread.start();  
        thread2.start();  
        thread3.start();  
    }  
  
}</span></strong>  
附(定义线程执行目标类)


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast;  
  
public class MyRunnable implements Runnable {  
  
    //重写run方法,供线程调用  
    @Override  
    public void run() {  
  
        //获取当前执行的线程  
        Thread currentThread = Thread.currentThread();  
        String name = currentThread.getName();  
          
        for (int i = 0; i < 100; i++) {  
            System.out.println(name+":"+i);  
        }  
    }  
  
}</span></strong>  
附2(定义自己的线程类)


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast;  
public class MyThread extends Thread {  
  
    public MyThread() {  
    }  
    public MyThread(String name) {  
        super(name);  
    }  
    /* 
     * 重写该线程中的"main"方法,实际上就是run方法 
     */  
    @Override  
    public void run() {  
          
        String thisThreadName = getName();  
          
        for (int i = 0; i < 100; i++) {  
            System.out.println(thisThreadName+":"+i);  
        }  
    }  
      
}</span></strong>  


4)每一个线程均有优先级,优先级高的先执行,低的后执行。


public final void setPriority(int newPriority) 设置优先级
public final int getPriority()  获取优先级
优先级的范围:
1-10  默认5


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast2;  
/* 
 * 每一个线程均有优先级,优先级高的先执行,低的后执行。 
 * public final void setPriority(int newPriority) 设置优先级 
 * public final int getPriority()  获取优先级 
 * 优先级的范围: 
 *      1-10  默认5 
 */  
public class Demo {  
  
    public static void main(String[] args) {  
  
        MyThread mt = new MyThread("唐嫣");  
        MyThread mt2 = new MyThread("诗诗");  
          
        mt.setPriority(10);  
        mt2.setPriority(1);  
          
        mt.start();  
        mt2.start();  
    }  
  
}</span></strong>  


5)线程休眠
public static void sleep(long millis)  在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)


throws InterruptedException   


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast3;  
  
public class Demo {  
  
    public static void main(String[] args) {  
  
        MyThread mt = new MyThread("唐嫣");  
        MyThread mt2 = new MyThread("诗诗");  
          
        mt.setPriority(10);  
        mt2.setPriority(1);  
          
        mt.start();  
        mt2.start();  
    }  
  
}</span></strong>  


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast3;  
  
public class MyThread extends Thread {  
  
      
    public MyThread() {  
        super();  
    }  
  
    public MyThread(String name) {  
        super(name);  
    }  
  
    @Override  
    public void run() {  
          
          
        for (int i = 0; i < 100; i++) {  
            if(i==20) {  
                try {<span style="white-space:pre">   </span>//定义休眠时间  
                    Thread.sleep(10000);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
            System.out.println(getName()+":"+i);  
        }  
    }  
  
      
}</span></strong>  


6)线程加入
public final void join()  等待该线程终止.


throws InterruptedException


即调用方法时所在的线程,等待调用方法的线程执行完毕


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast4;  
  
public class Demo {  
  
    public static void main(String[] args) throws InterruptedException {  
  
        MyThread mt = new MyThread("唐嫣");  
        MyThread mt2 = new MyThread("诗诗");  
          
        mt.setPriority(10);  
        mt2.setPriority(1);  
          
        mt.start();  
        mt2.start();  
        //等待mt线程结束,main方法在继续与mt2夺取cpu,继续执行  
        mt.join();  
          
        for (int i = 0; i < 100; i++) {  
            System.out.println(Thread.currentThread().getName()+":"+i);  
        }  
    }  
  
}</span></strong>  


7)线程礼让
public static void yield() 暂停当前正在执行的线程对象,并执行其他线程


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast5;  
  
public class Demo {  
  
    public static void main(String[] args) throws InterruptedException {  
  
        MyThread mt = new MyThread("唐嫣");  
        MyThread mt2 = new MyThread("诗诗");  
  
        mt.start();  
        mt2.start();  
          
    }  
  
}</span></strong>  


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast5;  
  
public class MyThread extends Thread {  
  
      
    public MyThread() {  
        super();  
    }  
  
    public MyThread(String name) {  
        super(name);  
    }  
  
    @Override  
    public void run() {  
          
        for (int i = 0; i < 100; i++) {  
            System.out.println(getName()+":"+i);  
            //定义线程礼让,直接用Thread调用方法</span></strong>  
[java] view plaincopy
<strong><span style="font-size:14px;"><span style="white-space:pre">          </span>Thread.yield();  
        }  
    }  
}</span></strong>  


8)守护线程
public final void setDaemon(boolean on) 设置守护线程


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast6;  
  
public class Demo {  
  
    public static void main(String[] args) throws InterruptedException {  
  
        MyThread mt = new MyThread("小A");  
        MyThread mt2 = new MyThread("小B");  
        MyThread mt3 = new MyThread("大C");  
          
        mt.setPriority(10);  
        mt2.setPriority(10);  
        mt3.setPriority(1);  
        //线程mt yu mt2 为守护线程  
        mt.setDaemon(true);  
        mt2.setDaemon(true);  
          
          
        mt.start();  
        mt2.start();  
        mt3.start();  
          
    }  
  
}</span></strong>  
9)线程中断
public final void stop() 已过时,结束线程.杀掉线程!


public void interrupt()  中断线程


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast7;  
  
public class Demo {  
  
    public static void main(String[] args) throws InterruptedException {  
  
        MyThread mt = new MyThread("小A");  
        MyThread mt2 = new MyThread("大C");  
          
        mt.start();  
        mt2.start();  
          
        Thread.sleep(3000);  
        //杀死线程  
//      mt.stop();  
//      mt2.stop();  
        //线程中断  
        mt.interrupt();  
        mt2.interrupt();  
    }  
  
}</span></strong>  


10)线程安全问题:
线程随机访问性


有多个线程并行


多个线程有共享数据


多个线程操作了共享数据


原子性:


原子性操作


synchronized 同步关键字


synchronized代码块用来规范一个原子性操作


格式:
synchronized(锁对象){//该对象可以是任意对象


需要同步的代码;


}


锁: 就是一个任意对象。


只要多线程使用同一把锁,则这个多个线程被锁住的代码就同步了


代码演示:




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast8;  
  
public class Demo {  
  
    public static void main(String[] args) {  
          
        Tickets tickets = new Tickets();  
          
        Thread thread = new Thread(tickets,"柳岩");  
        Thread thread2 = new Thread(tickets,"花千骨");  
          
        thread.start();  
        thread2.start();  
    }  
  
}</span></strong>  
[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast8;  
/* 
 * 定义线程执行目标类:票 
 */  
public class Tickets implements Runnable {  
  
    int number = 100;  
    Object lock = new Object();  
      
    //重写run方法,卖票的方法  
    @Override  
    public void run() {  
          
        while(true) {  
            //使用synchronized将一个原子性操作包裹,是其同步,不同的线程需要使用相同的锁  
            synchronized (lock) {  
                try {  
                    //使线程睡眠10毫秒,加大出现安全问题的几率  
                    Thread.sleep(10);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                //只要有票就可以卖  
                if(number>0) {  
                    //将数字打印即卖票的过程  
                    System.out.println(Thread.currentThread().getName()+"正在销售第"+ number +"张票");  
                    //每次卖完一张票可以减少1  
                    number--;  
                }  
            }  
              
        }  
    }  
  
}</span></strong>  


同步方法的锁是其所在对象


静态同步方法的锁就是类本身


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;"><strong>package cn.itcast9;  
/* 
 * 定义线程执行目标类:票 
 */  
public class Tickets implements Runnable {  
  
    static int number = 100;  
    Object lock = new Object();  
    int x = 0;  
      
    //同步方法:直接在方法声明上加synchronized同步关键字修饰  
    /* 
    public synchronized void method() { 
        synchronized (lock) { 
            try { 
                Thread.sleep(10); 
            } catch (InterruptedException e) { 
                e.printStackTrace(); 
        } 
            if(number>0) { 
                System.out.println(Thread.currentThread().getName()+"正在销售第"+ number +"张票"); 
                number--; 
            } 
        } 
    } 
    */  
    //静态同步方法:直接在方法声明上加synchronized同步关键字修饰  
    public static synchronized void method() {  
        try {  
            Thread.sleep(10);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        if(number>0) {  
            System.out.println(Thread.currentThread().getName()+"正在销售第"+ number +"张票");  
            number--;  
        }  
    }  
}</strong></span>  


二.LOCK锁
Lock锁:


另外一种同步解决方案




ReentrantLock:Lock接口的子类对象


void lock() 上锁


void unlock() 解锁


代码演示:




[java] view plaincopy
<span style="font-size:14px;"><strong>package cn.itcast2;  
  
public class Demo {  
  
    public static void main(String[] args) {  
          
        Tickets tickets = new Tickets();  
          
        Thread thread = new Thread(tickets,"柳岩");  
        Thread thread2 = new Thread(tickets,"花千骨");  
          
        thread.start();  
        thread2.start();  
    }  
  
}</strong></span>  
[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast2;  
  
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
  
/* 
 * 定义线程执行目标类:票 
 */  
public class Tickets implements Runnable {  
  
    int number = 100;  
    Lock lock = new ReentrantLock();  
      
    //重写run方法,卖票的方法  
    @Override  
    public void run() {  
          
        while(true) {  
              
            lock.lock();  
            try {  
                //使线程睡眠10毫秒,加大出现安全问题的几率  
                Thread.sleep(10);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            //只要有票就可以卖  
            if(number>0) {  
                //将数字打印即卖票的过程  
                System.out.println(Thread.currentThread().getName()+"正在销售第"+ number +"张票");  
                //每次卖完一张票可以减少1  
                number--;  
            }  
            lock.unlock();  
        }  
              
    }  
  
}</span></strong>  




三.等待唤醒机制
当出现对同一资源的生产与消费时,可以使用多线程完成对同一资源的操作.而消费者需要等待生产者生产后才能消费,生产者也需要等待消费者消费后才能生产.于是出现了生产者消费者问题.这时可以使用等待唤醒机制完成相关需求


涉及方法:
涉及并非是Thread类的方法,而是Object类的两个方法:因为锁可以为共享数据本身可以是任意的对象,在runnable中进行等待唤醒当前所在线程.
等待:
public final void wait() throws InterruptedException
让当前线程进入等待状态,如果线程进入该状态,不唤醒或打断,不会解除等待状态
进入等待状态时会释放锁.
唤醒:
public final void notify()
唤醒正在等待的线程
继续等待之后的代码执行
sleep与wait的区别:
sleep指定时间,wait可指定可不指定
sleep释放执行权,不释放锁.因为一定可以醒来.
wait释放执行权与锁.


四篇代码演示:


1.定义共享数据Person类




[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast5;  
  
/* 
 * 定义共享数据Person类 
 */  
public class Person {  
  
    private String name;  
    private int age;  
    //定义标志位,记录现在是否有数据.如果true说明有数据,生产者可以等待.反之false,消费者等待  
    boolean flag = false;  
  
    public Person() {  
        super();  
    }  
  
    public Person(String name, int age) {  
        super();  
        this.name = name;  
        this.age = age;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
  
    public void setAge(int age) {  
        this.age = age;  
    }  
  
    @Override  
    public String toString() {  
        return "Person [name=" + name + ", age=" + age + "]";  
    }  
  
}</span></strong>  
2.生产者的生产执行目标类


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast4;  
/* 
 * 生产者的生产执行目标 
 */  
public class PRunnable implements Runnable {  
  
    //定义Person类型的成员变量,用于传入与其他线程共享的数据  
    private Person p;  
      
    //定义标志位,用来区别每次赋值的人名与年龄  
    int x = 0;  
      
    public PRunnable(Person p) {  
        this.p = p;  
    }  
  
    @Override  
    public void run() {  
  
        while(true) {  
            synchronized (p) {  
                if(x%2==0) {  
                    p.setName("柳岩");  
                    p.setAge(32);  
                } else {  
                    p.setName("唐嫣");  
                    p.setAge(28);  
                }  
                x++;  
            }  
        }  
    }  
  
}</span></strong>  


3.消费者的生产执行目标类


[java] view plaincopy
<strong><span style="font-size:14px;">package cn.itcast5;  
/* 
 * 消费者的生产执行目标 
 */  
public class CRunnable implements Runnable {  
  
    //定义Person类型的成员变量,用于传入与其他线程共享的数据  
    private Person p;  
      
    public CRunnable(Person p) {  
        this.p = p;  
    }  
      
    @Override  
    public void run() {  
          
        while(true) {  
            synchronized (p) {  
                //如果没有数据,消费者就等待  
                if(!p.flag) {  
                    try {  
                        p.wait();  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
                //如果有数据了,就消费  
                System.out.println(p.getName() + ":" + p.getAge());  
                //消费者消费后将标志位置为没有数据  
                p.flag = false;  
                //如果有生产的线程在等待,就将生产的线程唤醒  
                p.notify();  
            }  
        }  
    }  
  
}</span></strong>  


4.演示类
生产者为一个生产线程  P
消费者为一个消费线程  C
共享数据:
一个Person对象
消费:打印该对象的姓名与年龄
生产:为这个对象的年龄和姓名赋不同的值




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;"><strong>package cn.itcast5;  
  
public class Demo {  
  
    public static final Object lock = new Object();  
      
    public static void main(String[] args) {  
  
        //创建共享数据  
        Person p = new Person("唐嫣", 28);  
          
        //创建生产者与消费者的线程执行目标类对象  
        PRunnable pr = new PRunnable(p);  
        CRunnable cr = new CRunnable(p);  
          
        //创建线程对象  
        Thread PThread = new Thread(pr);  
        Thread CThread = new Thread(cr);  
          
        //开启线程  
        PThread.start();  
        CThread.start();  
    }  
  
}</strong></span>  


四.ThreadGroup:线程组
public final ThreadGroup getThreadGroup()  获取其所在的线程组


代码演示:




[java] view plaincopy
<strong><span style="font-family:SimHei;font-size:14px;">package cn.itcast6;  
  
public class Demo {  
  
    public static void main(String[] args) {  
  
        ThreadGroup group = new ThreadGroup("唐嫣的线程组");  
          
        Thread thread = new Thread();  
        Thread thread2 = new Thread(group,"嫣嫣");  
        Thread thread3 = new Thread(group,"小嫣");  
          
        System.out.println(thread.getThreadGroup().getName());  
        System.out.println(thread);  
          
        System.out.println(thread2.getThreadGroup().getName());  
        System.out.println(thread2);  
        System.out.println(thread3.getThreadGroup().getName());  
        System.out.println(thread3);  
    }  
  
}</span></strong>  
五.ExecutorService:线程池
该类可以使用其对应的工厂类来创建对象
Future<?> submit(Runnable task)  提交任务调用线程池中的线程执行




Executors:线程池创建工厂类
public static ExecutorService newFixedThreadPool(int nThreads)  创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程
代码演示:


[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;"><strong>package cn.itcast7;  
  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
  
public class Demo {  
  
    public static void main(String[] args) {  
  
        //使用工厂创建线程池对象  
        ExecutorService es = Executors.newFixedThreadPool(3);  
        //创建自定义的线程执行目标类对象  
        MyRunnable mr = new MyRunnable();  
        //提交任务,共线程池中的线程执行  
        es.submit(mr);  
        //关闭  
        es.shutdown();  
    }  
  
}</strong></span>  
[java] view plaincopy
<strong><span style="font-family:SimHei;font-size:14px;">package cn.itcast7;  
  
public class MyRunnable implements Runnable {  
  
    @Override  
    public void run() {  
          
        for (int i = 0; i < 100; i++) {  
            System.out.println(i);  
        }  
    }  
  
}</span></strong>  




ExecutorService:
Future<?> submit(Runnable task)  提交任务,返回结果
<T> Future<T> submit(Callable<T> task)  提交任务,返回结果
 
Callable<V>:返回结果并且可能抛出异常的任务,即就是有返回结果的Runnable
V call() throws Exception
 
Future:
表示运行的结果
代码演示:


[java] view plaincopy
<strong><span style="font-family:SimHei;font-size:14px;">package cn.itcast7;  
  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
  
public class Demo2 {  
  
    public static void main(String[] args) throws Exception {  
  
        method2();  
    }  
    //多线程的第三种实现方式  
    public static void method2() throws Exception {  
  
        //使用工厂创建线程池对象  
        ExecutorService threadPool = Executors.newFixedThreadPool(2);  
        //创建有返回值结果的执行目标类对象  
        MyCallable mc = new MyCallable();  
        //提交任务,返回结果  
        Future<String> result = threadPool.submit(mc);  
        //通过结果对象,返回方法返回的最终返回值  
        System.out.println(result.get());  
    }  
      
    public static void method() throws InterruptedException, ExecutionException {  
        ExecutorService threadPool = Executors.newFixedThreadPool(2);  
          
        Future<?> result = threadPool.submit(new Runnable() {  
            @Override  
            public void run() {  
                for (int i = 0; i < 10; i++) {  
                    System.out.println(i);  
                }  
            }  
        });  
          
        System.out.println(result.get());  
    }  
  
}</span></strong>  


[java] view plaincopy
<strong><span style="font-family:SimHei;font-size:14px;">package cn.itcast7;  
  
import java.util.concurrent.Callable;  
  
public class MyCallable implements Callable<String> {  
  
    @Override  
    public String call() throws Exception {  
          
        for (int i = 0; i < 10; i++) {  
            System.out.println(i);  
        }  
          
        return "我爱敲代码!";  
    }  
  
}</span></strong>  


六.Timer: 
定时器,可安排任务执行一次,或者定期重复执行 


构造:


public Timer()




提交定时任务: 


public void schedule(TimerTask task, long delay)  延迟指定时间后执行任务一次


public void schedule(TimerTask task,Date time)  在指定的事件执行任务一次


public void schedule(TimerTask task, long delay,long period)  延迟指定时间后执行任务一次,之后,每隔指定的时间再执行一次
public void schedule(TimerTask task,Date time,long period)  在指定的事件执行任务一次,每隔指定的时间再执行一次


public void cancel() 终止定时器




TimerTask: 定时任务


public abstract void run()  该定时器所在线程要执行的执行目标,就是执行的任务


public boolean cancel()  取消任务


代码演示:


[java] view plaincopy
<strong><span style="font-family:SimHei;font-size:14px;">package cn.itcast8;  
  
import java.util.Date;  
import java.util.Timer;  
import java.util.TimerTask;  
  
/* 
 * Timer: 定时器,可安排任务执行一次,或者定期重复执行。  
 *  
 * 构造: 
 * public Timer() 
 *  
 * 提交定时任务:  
 * public void schedule(TimerTask task, long delay)  延迟指定时间后执行任务一次 
 * public void schedule(TimerTask task,Date time)  在指定的事件执行任务一次 
 * public void schedule(TimerTask task, long delay,long period)  延迟指定时间后执行任务一次,之后,每隔指定的时间再执行一次 
 * public void schedule(TimerTask task,Date time,long period)  在指定的事件执行任务一次,每隔指定的时间再执行一次 
 * public void cancel() 终止定时器 
 *  
 * TimerTask: 定时任务 
 * public abstract void run()  该定时器所在线程要执行的执行目标,就是执行的任务 
 * public boolean cancel()  取消任务 
 */  
public class Demo {  
  
    public static void main(String[] args) {  
          
        //创建定时器对象  
        Timer timer = new Timer();  
          
        //创建定时任务  
        TimerTask tt = new TimerTask() {  
  
            @Override  
            public void run() {  
                System.out.println("日本地震!");  
            }  
              
        };  
          
        //安排任务  
//      timer.schedule(tt, 3000);  
        Date now = new Date();  
        Date date = new Date(new Date().getTime()+3000);  
          
        System.out.println(now);  
        timer.schedule(tt, date,2000);  
        System.out.println(date);  
          
//      timer.cancel();  
    }  
}</span></strong><span style="font-family: SimHei; font-size: 18px;">  
</span>  


七.单例设计模式
代码演示:




[java] view plaincopy
<strong>package cn.itcast9;  
  
import java.io.IOException;  
  
/* 
 * 单例设计模式 
 */  
<span style="font-family:SimHei;">public class Demo {  
  
    public static void main(String[] args) throws IOException {  
  
        Person p = Person.getInstance();  
//      Person.p = null;  
        Person p2 = Person.getInstance();  
          
        System.out.println(p==p2);  
          
        Runtime runtime = Runtime.getRuntime();  
        runtime.exec("notepad");  
    }  
  
}</span></strong>  


饿汉设计模式:


[java] view plaincopy
package cn.itcast9;  
  
/* 
 * 饿汉式单例设计 
 */  
public class Person {  
  
    //构造方法私有化  
    private Person() {}  
      
    //定义私有静态成员变量  
    private static Person p = new Person();  
      
    //提供公共静态的方法,用于获取单例的对象  
    public static Person getInstance() {  
        return p;  
        }  
    }  
}  


懒汉式单例:


[java] view plaincopy
package cn.itcast9;  
/* 
 * 懒汉式单例 
 * 延迟加载 
 */  
public class Person {  
  
    public static Object lock = new Object();  
    //构造方法私有化  
    private Person() {}  
      
    //定义私有静态成员变量  
    private static Person p;  
      
    //提供公共静态的方法,用于获取单例的对象  
    public static Person getInstance() {  
        synchronized (lock) {  
            if (p == null) {  
                p = new Person();  
            }  
        }  
        return p;  
    }  
}  


懒汉式单例(在考虑线程安全的前提下又考虑到了效率问题)


[java] view plaincopy
package cn.itcast9;  
  
      
    //在考虑线程安全的前提下又考虑到了效率问题  
    public static Person getInstance() {  
        if(p == null) {  
            synchronized (lock) {  
                if (p == null) {  
                    p = new Person();  
                }  
            }  
        }  
        return p;  
    }  
    //只考虑线程安全的前提下  
    public static synchronized Person getInstance() {  
                if (p == null) {  
                    p = new Person();  
            }  
                    return p;  
        }  
    }     
}  






























































版权声明:本文为博主原创文章,未经博主允许不得转载。
0 0
原创粉丝点击