java 多线程学习笔记3-单例设计 线程间通信 互斥锁

1、多线程-单例设计模式:保证类在内存中只有一个对象。例如:(Runtime类)
    a、控制类的创建,不让其他类来创建本类的对象。private
b、在本类中定义一个本类的对象。Singleton s;
c、提供公共的访问方式。  public static Singleton getInstance(){return s}


    (1)饿汉式 开发用这种方式。
        //饿汉式
        class Singleton {
            private Singleton(){}//1,私有构造函数,不能创建对象
            private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
            public static Singleton getInstance() { //3,对外提供公共的访问方法,定义static可以使用 类名.方法 调用,定义public为了让其他类调用。
                return s;//返回这个对象
            }
            public static void print() {
                System.out.println("abc");
            }
        }
        
        内存中只有一个实例对象,导入的时候就创建好了
        
    (2)懒汉式 面试写这种方式。存在多线程访问问题,不建议使用
        //懒汉式
        class Singleton {
            private Singleton(){}//1,私有构造函数,不能创建对象
            private static Singleton s = new Singleton();//2,创建本类对象,定义static是为了可以使用 类名.方法 调用,定义private是为了不让其他类访问修改。
            public static Singleton getInstance() { //3,调用的时候判断。
if(s == null)
                        //可能存在 线程1,线程2 同时创建的问题
s = new Singleton();
return s;
}
            public static void print() {
                System.out.println("abc");
            }
        }
        
    (3)第三种格式,比较简单
        class Singleton {
            private Singleton() {}
            public static final Singleton s = new Singleton();//final是最终的意思,被final修饰的变量不可以被更改
        } 




    Runtime就是一个单例设计模式
        Runtime r = Runtime.getRuntime();
        r.exec("shutdown -s -t 30"); //30秒后关机


        
        
2、多线程-Timer类):Timer类:计时器


        public class Demo_Timer {


            public static void main(String[] args) throws InterruptedException {
                Timer t = new Timer();//创建Timer对象
                t.schedule(new MyTimerTask(), new Date(114,9,15,10,54,20),3000);
                
                while(true) {
                    System.out.println(new Date());
                    Thread.sleep(1000);
                }
            }
        }
        class MyTimerTask extends TimerTask {
            @Override
            public void run() {
                System.out.println("时间到");
            }
        }
        
3、多线程-两个线程间通信
    多个线程并发执行时, 在默认情况下CPU是随机切换线程的
    如果我们希望他们有规律的执行, 就可以使用通信, 例如每个线程执行一次打印。
    
    如果希望线程等待, 就调用wait()
    如果希望唤醒等待的线程, 就调用notify();
    这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用
    


    public class Demo1_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) {
                            
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print2();
                        } catch (InterruptedException e) {
                            
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }


    }


    //等待唤醒机制
    class Printer {
        private int flag = 1;
        public void print1() throws InterruptedException {
            synchronized(this) {
                if(flag != 1) {
                    this.wait(); //当前线程等待
                }
                System.out.print("你");
                System.out.print("好");
                System.out.print("啊");
                System.out.print("\r\n");
                flag = 2;
                this.notify(); //随机唤醒单个等待的线程
            }
        }
        
        public void print2() throws InterruptedException {
            synchronized(this) {
                if(flag != 2) {
                    this.wait();
                }
                System.out.print("C");
                System.out.print("S");
                System.out.print("D");
                System.out.print("N");
                System.out.print("\r\n");
                flag = 1;
                this.notify();
            }
        }
    }


4、多线程-互斥锁(JDK1.5的新特性)
    使用ReentrantLock类的lock()和unlock()方法进行同步
    
    通信
使用ReentrantLock类的newCondition()方法可以获取Condition对象
需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
    
        public static void main(String[] args) {
                final Printer3 p = new Printer3();
                
                //创建3条线程
                new Thread() {
                    public void run() {
                        while(true) {
                            try {
                                p.print1();
                            } catch (InterruptedException e) {
                                
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
                
                new Thread() {
                    public void run() {
                        while(true) {
                            try {
                                p.print2();
                            } catch (InterruptedException e) {
                                
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
                
                new Thread() {
                    public void run() {
                        while(true) {
                            try {
                                p.print3();
                            } catch (InterruptedException e) {
                                
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
            }


        }


        class Printer3 {
            private ReentrantLock r = new ReentrantLock();
            //给每个线程设置不同的Condition对象
            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(); //获取锁
                    if(flag != 1) {
                        c1.await();
                    }
                    System.out.print("你");
                    System.out.print("好");
                    System.out.print("啊");
                    System.out.print("\r\n");
                    flag = 2;
                    //this.notify(); //随机唤醒单个等待的线程
                    c2.signal();                            //唤醒等待线程2
                r.unlock(); //释放锁
            }
            
            public void print2() throws InterruptedException {
                r.lock();
                    if(flag != 2) {
                        c2.await();
                    }
                    System.out.print("C");
                    System.out.print("S");
                    System.out.print("D");
                    System.out.print("N");
                    System.out.print("\r\n");
                    flag = 3;
                    //this.notify();
                    c3.signal();
                r.unlock();
            }
            
            public void print3() throws InterruptedException {
                r.lock();
                    if(flag != 3) {
                        c3.await();
                    }
                    System.out.print("1");
                    System.out.print("2");
                    System.out.print("3");
                    System.out.print("\r\n");
                    flag = 1;
                    c1.signal();
                r.unlock();
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值