zoukankan      html  css  js  c++  java
  • Java学习-第四天

    Day11
    
    /*
    
    
    进程:是一个正在被执行中的程序。
        每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
    
    线程:就是进程中的一个独立完成控制单元。
        线程在控制着进程的执行。
    
    一个进程中至少有一个线程。
    
    创建线程的第一种方式, 继承Thread类
    步骤:
    1.定义类继承Thread类
    2.复写Thread类中的run方法,(目的是将自定义代码存储在run方法中,让线程运行。)
    3.实例化定义的类,调用start方法,
    start方法有两个作用,1)启动线程 2)调用run方法
    
    
    为什么覆盖run方法呢
    Thread类用于描述线程。
    该类定义了一个功能,用于存储线程要运行而定代码,该存储功能就是run方法。
    也就是说Thread类中的run方法,用于存储线程运行的代码。
    
    */
    
    class D11Demo extends Thread
    {
        public void run()
        {
            for (int i=0;i<100;i++ )
            {
                System.out.println("---demo run---"+i);
            }
        }
    }
    
    class  D11TheradDemo
    {
        public static void main(String[] args) 
        {
            
            Demo d = new Demo();
            d.start();//开启线程并执行该线程的run方法。
            d.run();//仅仅是对象的函数调用,而线程创建了,并没有运行。
            //
            for (int i=0;i<100;i++ )
            {
                System.out.println("---mian run---"+i);
    
            }
    
        }
    }
    /*
    练习: 创建两个线程和主线程交替运行
    
    通过 this.getName()或Thread.currentThread() 方法可以获取线程名称
    */
    
    class D11Test1 extends Thread
    {
        public void run()
        {
            for (int i=0;i<30;i++ )
            {
                System.out.println(getName()+"---run---"+i);
            }
        }
    }
    
    
    class D11Test2 extends Thread
    {
        public void run()
        {
            for (int i=0;i<30;i++ )
            {
                System.out.println(getName()+"---run---"+i);
            }
        }
    }
    
    class D11Test3 extends Thread
    {
        public void run()
        {
            for (int i=0;i<30;i++ )
            {
                System.out.println(getName()+"---run---"+i);
            }
        }
    }
    
    class  D11TheradTestDemo
    {
        public static void main(String[] args) 
        {
            
            D11Test1 t1 = new D11Test1();
            t1.start(); 
    
            D11Test2 t2 = new D11Test2();
            t2.start(); 
    
            D11Test3 t3 = new D11Test3();
            t3.start(); 
            
            for (int i=0;i<30;i++ )
            {
                System.out.println("---mian run---"+i);
    
            }
    
        }
    }
    
    /*
    练习2
    需求:简单的买票程序。
    多个窗口同时买票。
    
    创建线程的第二种方法,实现 Runnable 接口
    步骤
    1.定义类实现Runnable接口
    2.覆盖Runnable接口中的run方法。
    将线程要运行的代码存放在run方法中)
    3.通过Thread类建立线程对象。
    4.将Runnable接口的子类对象作为实际参数给Thread类的构造函数。
        自定义的run方法所属的对象时Runnable接口的子类对象,所以要让线程调用指定对象的run方法,就必须明确该run方法的对象。
    5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
    
    
    两种方式的区别:
    Runnable方式:
        1.避免的单继承的局限性,在定义线程是建议使用该方式。
        2.线程代码存在Runnable子类的run方法中
    
    继承Thread方式:    
        1.有局限性,因为Java的单继承特性如果继承可Thread类限制了继承其他类。
        2.线程带代码存放在Thread子类的run方法中。
    */
    
    class D11Ticket implements  Runnable//Thread
    {
        private int tick = 100;
        
        public void run()
        {
            while(true)
            {
                if(tick >0)
                {
                    /*
                    try
                    {
                        Thread.sleep(10);
                    }
                    catch (Exception e)
                    {
                    }
                    */
    
                    /*
                    通过上面代码 Thread.sleep(10); 分析发现 打印出 0 -1 -2 等错票
                    多线程的运行出现的安全问题。
                    问题的原因:
                        当多条语句在操作同一个线程共享数据时,
                        一个线程对多条语句执行了一部分,还没有执行完毕时,
                        另一个线程参与进来执行,导致共享数据的错误。
                    解决方法:
                        对于多条操作的共享数据的语句,只能让一个线程都执行完毕。
                        在一个线程执行过程中,其他线程不可以参与执行。
                    
                    Java对于多线程的安全问题提供了一个同步代码块用于解决这种问题。
                    
                    格式如下:
                    synchronized(对象)
                    {
                    }
                        
                    */
                    System.out.println(Thread.currentThread().getName()+" Sale :"+ tick --);
                }
            }
        }
    }
    
    class D11TicketDemo
    {
        public static void main(String[] args) 
        {
            D11Ticket t1 = new D11Ticket();
            new Thread(t1).start();
            new Thread(t1).start();
            new Thread(t1).start();
            new Thread(t1).start();
            
        }
    }
    
    /*
    Java对于多线程的安全问题提供了一个同步代码块用于解决这种问题。
                    
                    格式如下:
                    synchronized(对象)
                    {
                    }
    
    对象如同锁,持有锁的线程可以再同步中执行,
    没有持有锁的线程即使获取到CPU的执行权,也进不去,因为没有锁。
    
    同步的前提:
    1.必须要有两个或者两个以上的线程。
    2.必须是多个线程使用同一个锁。
    
    同步的利弊:
    
    利:保证只用一个线程在执行,解决了多线程中多条语句在操作同一个线程共享数据时的安全问题。
    
    弊:多个线程都需要判断锁,较为消耗资源。
    
    */
    class D11Ticket2 implements  Runnable//Thread
    {
        private int tick = 100;
    
        Object obj = new Object();
        
        public void run()
        {
            while(true)
            {
                synchronized(obj)
                {
    
                    if(tick >0)
                    {
                        try
                        {
                            Thread.sleep(10);
                        }
                        catch (Exception e)
                        {
                        }
                        //
                        System.out.println(Thread.currentThread().getName()+" Sale :"+ tick --);
                    }
                }
            }
        }
    }
    
    class D11TicketDemo2
    {
        public static void main(String[] args) 
        {
            D11Ticket2 t1 = new D11Ticket2();
            new Thread(t1).start();
            new Thread(t1).start();
            new Thread(t1).start();
            new Thread(t1).start();
            
        }
    }
    
    /*
    练习3
    需求:
    银行有一个金库
    有两个存户分别存300斤黄金,每次存100斤,存3次。
    
    目的: 该程序是否有安全问题,如果有,如何解决?
    
    如何找问题:
    1.明确哪些代码是多线程执行代码。
    2.明确哪些是共享数据。
    3.明确多线程运行代码中哪些语句是操作共享数据的。
    
    
    */
    
    class  D11Bank
    {
        private int sum;
        
        //同步函数也可以解决这种问题。
    
        public synchronized void add(int n)
        {
            sum +=n;
            //
            try{Thread.sleep(1000);}catch (Exception e){}
            System.out.println("sum="+ sum);
        }
    }
    
    class D11Cus implements Runnable
    {
        private D11Bank b = new D11Bank();
        public void run()
        {
            for(int i =0; i<3 ;i++ )
            {
                b.add(100);
            }
        }
    }
    
    class D11BankDemo
    {
        public static void main(String[] args) 
        {
            D11Cus c = new D11Cus();
            //
            Thread t1 =    new Thread(c);
            Thread t2 = new Thread(c);
            //
            t1.start();
            t2.start();
    
    
        }
    }
    
    /*
    同步函数用的是哪一个锁呢?
        函数需要被对象调用,那么函数都有一个所属对象引用,就是this。
        所以同步函数使用的锁是this
        
        下面通过该程序进行验证:
        
        使用线程来卖票
        一个线程在同步代码中,一个线程在同步函数中。
        都在执行卖票动作
    */
    
    class D11Ticket3 implements  Runnable//Thread
    {
        private int tick = 100;
    
        Object obj = new Object();
        
        boolean flag = true;
    
        public void run()
        {
            if(flag)
            {
                while(true)
                {
                    synchronized(this)
                    {
                        if(tick >0)
                        {
                            try{Thread.sleep(10);}catch (Exception e){}
                            //
                            System.out.println(Thread.currentThread().getName()+" code Sale :"+ tick --);
                        }
                    }
                }
            }
            else
            {
                while(true)
                {
                    show();
                }
            }
        }
    
        public synchronized void show()
        {
            if(tick >0)
            {
                try{Thread.sleep(10);}catch (Exception e){}
                //
                System.out.println(Thread.currentThread().getName()+" function  Sale :"+ tick --);
            }        
        }
    }
    
    class D11TicketDemo3
    {
        public static void main(String[] args) 
        {
            D11Ticket3 t = new D11Ticket3();
            Thread t1 =    new Thread(t);
            Thread t2 = new Thread(t);
            //
            t1.start();
            try{Thread.sleep(10);}catch (Exception e){}
            t.flag =false;
            t2.start();
            
        }
    }
    
    
    /*
    如果同步函数被static修饰后,使用的锁是什么呢?
    
    静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
    类名.class 该对象的类型是Class
    
    所以
    静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
    */
    
    class D11Ticket4 implements  Runnable//Thread
    {
        private static int tick = 100;
    
        Object obj = new Object();
        
        boolean flag = true;
    
        public void run()
        {
            if(flag)
            {
                while(true)
                {
                    //synchronized(obj)
                    synchronized(D11Ticket4.class)
                    {
                        if(tick >0)
                        {
                            try{Thread.sleep(20);}catch (Exception e){}
                            //
                            System.out.println(Thread.currentThread().getName()+" code Sale :"+ tick --);
                        }
                    }
                }
            }
            else
            {
                while(true)
                {
                    show();
                }
            }
        }
    
        public static synchronized void show()
        {
            if(tick >0)
            {
                try{Thread.sleep(10);}catch (Exception e){}
                //
                System.out.println(Thread.currentThread().getName()+" function  Sale :"+ tick --);
            }        
        }
    }
    
    class D11TicketDemo4
    {
        public static void main(String[] args) 
        {
            D11Ticket4 t = new D11Ticket4();
            Thread t1 =    new Thread(t);
            Thread t2 = new Thread(t);
            //
            t1.start();
            try{Thread.sleep(10);}catch (Exception e){}
            t.flag =false;
            t2.start();
            
        }
    }
    
    /*
    重提 单例设计模式
    */
    
    /*
    //饿汉式
    class Single
    {
        private static final  Single s =new Single();
        private Single();
        public static Single getInstance()
        {
            return s;
        }
    }
    
    
    */
    
    
    
    //懒汉式
    class D11Single
    {
        private static D11Single s =null;
        private D11Single(){}
        public static D11Single getInstance()
        {    
            //双重判断
            if(s == null)
            {
                synchronized(D11Single.class)
                {
                    if(s == null)
                    {
                        s = new D11Single();
                    }
                }
            }
    
            return s;
        }
    }
    
    
    /*
    死锁
    
    同步中嵌套同步
    */
    class D11Ticket5 implements  Runnable//Thread
    {
        private static int tick = 100;
    
        Object obj = new Object();
        
        boolean flag = true;
    
        public void run()
        {
            if(flag)
            {
                while(true)
                {
                    synchronized(D11Ticket4.class)
                    {
                        show();
                    }
                }
            }
            else
            {
                while(true)
                {
                    show();
                }
            }
        }
    
        public static synchronized void show()
        {
            synchronized(D11Ticket4.class)
            {
                if(tick >0)
                {
                    try{Thread.sleep(20);}catch (Exception e){}
                    //
                    System.out.println(Thread.currentThread().getName()+" code Sale :"+ tick --);
                }
            }    
        }
    }
    
    class D11TicketDemo5
    {
        public static void main(String[] args) 
        {
            D11Ticket5 t = new D11Ticket5();
            Thread t1 =    new Thread(t);
            Thread t2 = new Thread(t);
            //
            t1.start();
            try{Thread.sleep(10);}catch (Exception e){}
            t.flag =false;
            t2.start();
            
        }
    }
    
    
    class D11TestLock implements Runnable
    {
        private boolean flag;
    
        D11TestLock(boolean flag)
        {
            this.flag = flag;
        }
    
        public void run()
        {
            if(flag)
            {
                synchronized(D11MyLock.locka)
                {
                    System.out.println("if locka");
                    synchronized(D11MyLock.lockb)
                    {
                        System.out.println("if lockb");
                    }
                }
            }
            else
            {
                System.out.println("else lockb");
                synchronized(D11MyLock.lockb)
                {
                    synchronized(D11MyLock.locka)
                    {
                        System.out.println("else locka");
                    }
                }
            }
        }
    }
    
    class  D11MyLock
    {
        static Object locka =  new Object();
        static Object lockb =  new Object();
    }
    
    
    class D11DeadLockTest
    {    
        public static void main(String[] args) 
        {
            Thread t1 =    new Thread(new D11TestLock(true));
            Thread t2 = new Thread(new D11TestLock(false));
            //
            t1.start();
            t2.start();
        }
    }
    
    Day12
    
    /*
    线程间通讯
    其实就是多个线程在操作同一个资源
    但是操作的动作不同
    
    wait();线程存储在线程池中
    notify();唤醒线程池中的线程,通常唤醒顶部的线程。
    notifyAll();;唤醒线程池中所有的线程
    
    这些作线程的方法要使用在同步中,因为要对持有监视器(锁)的线程操作。
    所以要使用在同步中,因为只有同步才具有锁。
    
    为什么这些操作线程的方法要定义在Object类中呢?
    因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁。
    只有同一个锁上的被wait()的线程,才可以被同一个锁上的notify()唤醒线程,不可以对不同锁中的线程进行唤醒。
    (也就是说,等待和唤醒线程的必须是同一个锁。)
    因为锁可以使任意对象,所以可以被任意对象调用的方法只能有Object,所以定义在Object类中。
    */
    import java.util.concurrent.locks.*;
    class D12Res
    {
        String name;
        String sex;
        boolean flag = false;
    }
    
    class D12Input implements Runnable
    {
        private D12Res r;
    
        D12Input(D12Res r)
        {
            this.r = r ;
        }
        public void run()
        {
            int i=0;
            while(true)
            {
                synchronized(r)
                {
                    if(r.flag)
                        try{r.wait();}catch (Exception e){}
                        
                    if(i%2==0)
                    {
                        r.name ="tom";
                        r.sex = "man";
                    }
                    else
                    {
                        r.name ="赫尔";
                        r.sex = "女";
                    }
                    i++;
    
                    r.flag =true;
                    //唤醒OutPut
                    r.notify();
                }            
            }
        }
    }
    
    
    class D12Output implements Runnable
    {
        private D12Res r;
    
        D12Output(D12Res r)
        {
            this.r = r ;
        }
        public void run()
        {
            while(true)
            {
                synchronized(r)
                {
                    if(!r.flag)
                        try{r.wait();}catch (Exception e){}
                    System.out.println(r.name+"   "+r.sex);
                    //
                    r.flag =false;
                    r.notify();
                }
            }
        }
    }
    
    class  D12InPutAndOutPutDemom
    {
        public static void main(String[] args) 
        {
            D12Res r = new D12Res();
    
            D12Input in = new D12Input(r);
            D12Output out = new D12Output(r);
            Thread t1 = new Thread(in);
            Thread t2 = new Thread(out);
    
            t1.start();
            t2.start();
        }
    }
    
    /*
        改进D12Res
    */
    
    class D12Res2
    {
        private String name;
        private String sex;
        private boolean flag = false;
    
        public synchronized void set(String name, String  sex )
        {
            if(flag)
                try{this.wait();}catch (Exception e){}
    
            this.name = name ;
            this.sex = sex;
    
            flag = true;
            this.notify();
        }
    
        public synchronized void out()
        {
            if(!flag)
                try{this.wait();}catch (Exception e){}
            System.out.println(this.name+"   "+this.sex);
            flag = false;
            this.notify();
        }
    
    }
    
    class D12Input2 implements Runnable
    {
        private D12Res2 r;
    
        D12Input2(D12Res2 r)
        {
            this.r = r ;
        }
        public void run()
        {
            int i=0;
            while(true)
            {
                if(i%2==0)
                    r.set("tom" ,"man");
                else
                    r.set("赫尔" ,"女");
                i++;        
            }
        }
    }
    
    
    class D12Output2 implements Runnable
    {
        private D12Res2 r;
    
        D12Output2(D12Res2 r)
        {
            this.r = r ;
        }
        public void run()
        {
            while(true)
            {
                r.out();
            }
        }
    }
    
    class  D12InPutAndOutPutDemom2
    {
        public static void main(String[] args) 
        {
            D12Res2 r = new D12Res2();
    
            new Thread(new D12Input2(r)).start();
            new Thread(new D12Output2(r)).start();
        }
    }
    
    
    class D12Resource
    {
        private String name;
        private int num =1;
        private Boolean flag = false;
    
        public synchronized void set(String name)
        {
            if(flag)
                try{this.wait();}catch (Exception e){}        
            this.name = name + "..." + num++;
            
            System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
            flag =true;
            this.notify();
    
        }
    
        public synchronized void out()
        {
            if(!flag)
                try{this.wait();}catch (Exception e){}        
            System.out.println(Thread.currentThread().getName()+".........消费者........."+this.name);
            flag =false;
            this.notify();
        }
    }
    
    class D12Producer implements Runnable
    {
        private D12Resource res;
        
        D12Producer(D12Resource res)
        {
            this.res = res;
        }
    
        public void run()
        {
            while(true)
                res.set("商品");
        }
    }
    
    class D12Consumer implements Runnable
    {
        private D12Resource res;
        
        D12Consumer(D12Resource res)
        {
            this.res = res;
        }
    
        public void run()
        {
    
            while(true)
                res.out();
        }
    }
    
    class D12ResourceDemo
    {
        public static void main(String[] args) 
        {
            D12Resource r = new D12Resource();
    
            D12Producer pro = new D12Producer(r);
            D12Consumer con = new D12Consumer(r);
            
            Thread t1 = new Thread(pro);
            Thread t2 = new Thread(pro);
            Thread t3 = new Thread(pro);
            Thread t4 = new Thread(pro);
            Thread t5 = new Thread(con);
            Thread t6 = new Thread(con);
            Thread t7 = new Thread(con);
            Thread t8 = new Thread(con);
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
            t7.start();
            t8.start();
            /*
            运行后会发现存在生产一个消费多个或生产多个消费单个(有些生产被无视)的异常。
            运行异常如下:
            
    
            Thread-2...生产者...商品...123
            Thread-3...生产者...商品...133
            Thread-4.........消费者.........商品...133
            Thread-2...生产者...商品...134
            Thread-4.........消费者.........商品...134
            ...
            ...
            ...
            ...
            ...
            Thread-0...生产者...商品...1453
            Thread-4.........消费者.........商品...1453
            Thread-1...生产者...商品...1454
            Thread-2...生产者...商品...1455
            Thread-5.........消费者.........商品...1455
            Thread-6.........消费者.........商品...1455
            Thread-7.........消费者.........商品...1455
            Thread-8.........消费者.........商品...1455
            E:ProgramCodeJavaJAVA毕向东>
    
            */
        }
    }
    
    /*
    运行后会发现存在消费多个或生产多个的异常。
    产生问题的原因是:
    线程在被唤醒的时候没有判断自己有没有是否具备执行生产或消费。从而导致消费多个或生产多个。
    即生产线程被生产线程唤醒,其余消费被等待的时候,唤醒的生产线程所做的生产会覆盖前一个生产线程的生产,这样大的生产是不合法的。
    
    解决办法:
    线程被唤醒后,判断是否具备执行。(if 改为 while)
    不过执行到一定时间后,容易出现只唤醒本方线程的情况,导致程序中的所有线程都处于等待状态。
    解决办法: notify 改为 notifyAll
    这样就可以解决这个问题了。对于多个生产者和消费者适用于这样的方法。
    
    为什么定义while判断标记?
    因为让被唤醒的线程再一次判断标记,防止出错。
    
    为什么定义为notifyAll?
    1.因为需要唤醒对方线程
    2.因为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
    
    */
    class D12Resource2
    {
        private String name;
        private int num =1;
        private Boolean flag = false;
    
        public synchronized void set(String name)
        {
            while(flag)
                try{this.wait();}catch (Exception e){}        
            this.name = name + "..." + num++;
            
            System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
            flag =true;
            this.notifyAll();
    
        }
    
        public synchronized void out()
        {
            while(!flag)
                try{this.wait();}catch (Exception e){}        
            System.out.println(Thread.currentThread().getName()+".........消费者........."+this.name);
            flag =false;
            this.notifyAll();
        }
    }
    
    class D12Producer2 implements Runnable
    {
        private D12Resource2 res;
        
        D12Producer2(D12Resource2 res)
        {
            this.res = res;
        }
    
        public void run()
        {
            while(true)
                res.set("商品");
        }
    }
    
    class D12Consumer2 implements Runnable
    {
        private D12Resource2 res;
        
        D12Consumer2(D12Resource2 res)
        {
            this.res = res;
        }
    
        public void run()
        {
    
            while(true)
                res.out();
        }
    }
    
    class D12ResourceDemo2
    {
        public static void main(String[] args) 
        {
            D12Resource2 r = new D12Resource2();
    
            D12Producer2 pro = new D12Producer2(r);
            D12Consumer2 con = new D12Consumer2(r);
            
            Thread t1 = new Thread(pro);
            Thread t2 = new Thread(pro);
            Thread t3 = new Thread(pro);
            Thread t4 = new Thread(pro);
            Thread t5 = new Thread(con);
            Thread t6 = new Thread(con);
            Thread t7 = new Thread(con);
            Thread t8 = new Thread(con);
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
            t7.start();
            t8.start();
    
        }
    }
    
    /*
    
    JDK5.0升级 改版生产者消费者
    换型
    */
    
    class D12Resource3
    {
        private String name;
        private int num =1;
        private Boolean flag = false;
        //
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        
        public void set(String name) throws InterruptedException
        {
            lock.lock();
    
            try
            {
                while(flag)
                condition.await();
                this.name = name + "..." + num++;
            
                System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
                flag =true;
                condition.signalAll();    
            }        
            finally
            {
                lock.unlock();
            }
    
        }
    
        public void out() throws InterruptedException
        {
        
            lock.lock();
            try
            {
                while(!flag)
                    condition.await();
                System.out.println(Thread.currentThread().getName()+".........消费者........."+this.name);
                flag =false;
                condition.signalAll();    
            }
            finally
            {
                lock.unlock();
            }
        }
    }
    
    class D12Producer3 implements Runnable
    {
        private D12Resource3 res;
        
        D12Producer3(D12Resource3 res)
        {
            this.res = res;
        }
    
        public void run()
        {
            while(true)
            {
                try
                {
                    res.set("商品");
                }
                catch (InterruptedException e)
                {
                }
            }
        }
    }
    
    class D12Consumer3 implements Runnable
    {
        private D12Resource3 res;
        
        D12Consumer3(D12Resource3 res)
        {
            this.res = res;
        }
    
        public void run()
        {
    
            while(true)
            {
                try
                {
                    res.out();
                }
                catch (InterruptedException e)
                {
                }
            }
        }
    }
    
    class D12ResourceDemo3
    {
        public static void main(String[] args) 
        {
            D12Resource3 r = new D12Resource3();
    
            D12Producer3 pro = new D12Producer3(r);
            D12Consumer3 con = new D12Consumer3(r);
            
            Thread t1 = new Thread(pro);
            Thread t2 = new Thread(pro);
            Thread t3 = new Thread(pro);
            Thread t4 = new Thread(pro);
            Thread t5 = new Thread(con);
            Thread t6 = new Thread(con);
            Thread t7 = new Thread(con);
            Thread t8 = new Thread(con);
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
            t7.start();
            t8.start();
    
        }
    }
    
    
    /*
    
    改进升级版生产者消费者
    定义一两个Condition:condition_pro condition_con
    生产者线程等待,唤醒消费者等待线程
    消费者线程等待,换型生产者等待线程
    即本方线程只唤醒对方线程的操作。
    
    JDK1.5 中提供了多线程的升级解决方案。
    1.将同步 synchronized 替换为 Lock 操作
    2.将Object中的 wait,notify,notifyAll 替换为condiction 对象,该对象可以对 Lock锁 进行获取
    
    
    */
    
    class D12Resource4
    {
        private String name;
        private int num =1;
        private Boolean flag = false;
        //
        private Lock lock = new ReentrantLock();
        private Condition condition_pro = lock.newCondition();
        private Condition condition_con = lock.newCondition();
        
        public void set(String name) throws InterruptedException
        {
            lock.lock();
    
            try
            {
                while(flag)
                condition_pro.await();
                this.name = name + "..." + num++;
            
                System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
                flag =true;
                condition_con.signalAll();    
            }        
            finally
            {
                lock.unlock();
            }
    
        }
    
        public void out() throws InterruptedException
        {
        
            lock.lock();
            try
            {
                while(!flag)
                    condition_con.await();
                System.out.println(Thread.currentThread().getName()+".........消费者........."+this.name);
                flag =false;
                condition_pro.signalAll();    
            }
            finally
            {
                lock.unlock();
            }
        }
    }
    
    class D12Producer4 implements Runnable
    {
        private D12Resource4 res;
        
        D12Producer4(D12Resource4 res)
        {
            this.res = res;
        }
    
        public void run()
        {
            while(true)
            {
                try
                {
                    res.set("商品");
                }
                catch (InterruptedException e)
                {
                }
            }
        }
    }
    
    class D12Consumer4 implements Runnable
    {
        private D12Resource4 res;
        
        D12Consumer4(D12Resource4 res)
        {
            this.res = res;
        }
    
        public void run()
        {
    
            while(true)
            {
                try
                {
                    res.out();
                }
                catch (InterruptedException e)
                {
                }
            }
        }
    }
    
    class D12ResourceDemo4
    {
        public static void main(String[] args) 
        {
            D12Resource4 r = new D12Resource4();
    
            D12Producer4 pro = new D12Producer4(r);
            D12Consumer4 con = new D12Consumer4(r);
            
            Thread t1 = new Thread(pro);
            Thread t2 = new Thread(pro);
            Thread t3 = new Thread(pro);
            Thread t4 = new Thread(pro);
            Thread t5 = new Thread(con);
            Thread t6 = new Thread(con);
            Thread t7 = new Thread(con);
            Thread t8 = new Thread(con);
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
            t7.start();
            t8.start();
    
        }
    }
  • 相关阅读:
    selenium python 中浏览器操作
    wireshark基础学习—第三部分wireshark的过滤器语法
    wireshark基础学习—第二部分wireshark的基础操作
    wireshark基础学习—第一部分wireshark的基础知识
    Python 之 tuple
    Python 之 list
    python socketpool:通用连接池
    APScheduler 3.0.1浅析
    检查SDE版本健康情况的常用SQL语句
    免重启下刷新新添加的磁盘信息
  • 原文地址:https://www.cnblogs.com/lhy_2011/p/4020216.html
Copyright © 2011-2022 走看看