day25 Java学习 多线程

 多线程( 单列设计模式 :* 掌握)

    单例设计模式 :保证类在内存中只有一个对象。

     饿汉式和懒汉式的区别:

         * 1. 饿汉式时空间换时间;懒汉式是时间换空间 。(不推荐懒汉式的使用)

         * 2. 在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象 。

      单列的三种写法:

/*
 * 饿汉式 
 */
class Singleton{
    //1.私有构造方法,其他类不能访问该类构造方法
    private Singleton () {};
    //2.创建本类对象
    private  static Singleton s=new Singleton();  //成员变量Singleton s 被私有,不能通过类名 . 调用
    //3.对外提供公共的访问方法
    public static Singleton getInstance() {       //获取实例
        return s;        
    }        
}

/*
 * 懒汉式 :单例延迟加载模式(单列模式不用的,因为有可能创建多个对象)
 */
class Singleton{
    //1.私有构造方法,其他类不能访问该类构造方法
    private Singleton () {};
    //2.声明一个引用
    private static Singleton s;
    //3.对外提供公共的访问方法
    public static Singleton getInstance() {       //获取实例
      if(s==null){
         s=new Singleton();
           }
        return s;        
    }        
}
/*
 * 第三种
 */
class Singleton{
    //1.私有构造方法,其他类不能访问该类构造方法
    private Singleton () {};
    //2.创建本类对象
    public static final Singleton s=new Singleton();  // 添加final后不会被改变 s
    
}
单列设计模式

 

  多线程( Runtime类)

     Runtime类是一个单例类。

    public static void main(String[] args) throws IOException {
        // 操作同一个对象 shutdown
   Runtime r= Runtime.getRuntime();   //获取运行时对象
   r.exec("shutdown -s -t 300");      // 修改了
   r.exec("shutdown -a");             // 根据上一个对象去修改
    }
例子

 

  多线程( Timer类 :* 掌握)

      Timer类 :计时器。

public class Dome3_Timer {

    public static void main(String[] args) throws InterruptedException {
       
        Timer t=new Timer();     //创建一个计时器
        //schedule():在指定时间安排指定任务。
        //第一个参数是指定任务,第二个参数是执行的时间,第三个参数是过多长时间再重复执行
        t.schedule(new MyTimer(),new Date(119, 5, 6, 0, 57, 4 0),2000);
           while (true) {
               Thread.sleep(1000);
            System.out.println(new Date());
        }
    }

}

class MyTimer extends TimerTask{

    @Override
    public void run() {
        
        System.out.println("起来读书");    
    }    
}
schedule()

 

多线程( 两个线程间的通信:* 掌握)

1.什么时候需要通信:

       * 多个线程并发执行时,在默认情况下CPU时随机切换线程的。

       * 如果我们希望他们有规律的执行,就可以使用通讯 。

2.怎么通信:

       * wait():当前线程等待

       * notify():随机唤醒单个等待的线程

       * 这两个方法必须在同步代码中执行,并且使用同步锁对象来调用。

public class Dome1_Notify {

    public static void main(String[] args) {
    final  Printer p=new Printer();
    new Thread() {
          public void run () {
              while(true) {
              try {
                p.print1();
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
          }      
          }
      }.start();
       
      
      new Thread() {
          public void run () {
              while(true) {
              try {
                p.print2();
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
          }      
          }
      }.start();
    }

}
//等待唤醒机制
class Printer{
    private  int flag=1;
    public void print1() throws InterruptedException {
        synchronized (this) {
            if (flag!=1) {
                this.wait();
            }
                System.out.print("a");
                System.out.print("b");
                System.out.print("c");
                System.out.print("\r\n");
                flag=2;
                this.notify();    //随机唤醒单个等待的线程
            }
        }

    
    public void print2() throws InterruptedException {
        synchronized (this) {
            if (flag!=2) {
                this.wait();     //this.wait():当前线程等待
            }
            System.out.print("d");
            System.out.print("e");
            System.out.print("f");
            System.out.print("\r\n");
            flag=1;
            this.notify();          //this.notify():随机唤醒单个等待的线程
            }            
}
}
例子

 

  多线程( 线程间的通信注意问题)

    1. 在同步代码块中,用那个对象锁,就用哪个对象调用wait 方法。

    2. 因为锁对象是可以任意对象,Object是所有的类的基类,所以wait( ) 和notify( )需要定义在Object这个类中。

   

     3.sleep方法和wait方法的区别

         ( 1 ) * sleep方法必须传入参数,参数就是时间,时间到了就自动醒来。

                     * wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待。

         ( 2 ) * sleep方法在同步函数或同步代码块中,不是放锁。

                     * wait方法在同步函数或者同步代码块中,释放锁。

 

  多线程( JDK1.5的新特性互斥锁:*掌握) 

     1.同步:

            *使用ReentrantLock的 lock( ) 和 unlock( )方法进行听不。

      2. 通信:

            * 使用ReentrantLock类的newCondition( )方法可以获取Condition对象。

            * 需要等待的时候使用Condition的await ( ) 方法,唤醒的时候用signal( )方法。

            * 不用的线程使用不同的Condition,这样就能区分唤醒的时候找到那个线程了。

class Printer3 {
    private ReentrantLock r = new ReentrantLock();
    private Condition c1 = r.newCondition();
    private Condition c2 = r.newCondition();
    private Condition c3 = r.newCondition();
    private int flag = 1;

    public void print1() throws InterruptedException {
        r.lock();             //lock():获取锁
        if (flag != 1) {
            c1.await();
        }
        System.out.print("a");
        System.out.print("b");
        System.out.print("c");
        System.out.print("\r\n");
        flag = 2;
        c2.signal();      //signal():释放锁
    }
    
    public void print2() throws InterruptedException {
        r.lock();
        if (flag != 2) {
            c2.await();
        }
        System.out.print("e");
        System.out.print("f");
        System.out.print("g");
        System.out.print("\r\n");
        flag = 3;
        c3.signal();
    }
    public void print3() throws InterruptedException {
        r.lock();
        if (flag != 3) {
            c3.await();
        }
        System.out.print("h");
        System.out.print("i");
        System.out.print("j");
        System.out.print("\r\n");
        flag = 1;
        c1.signal();
    }
    
    
}
JDK1.5新特性互斥锁

 

posted @ 2019-06-06 01:40  锋XX  阅读(126)  评论(0编辑  收藏  举报