多线程09-Lock和Condition

1.概念

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。

 

2.案例

package org.lkl.thread;



import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;



public class LockFoo {

    /**

     * 两个线程打印姓名

     */

    

    

    public static void main(String[] args) {

        final Outputter out = new Outputter() ;

        new Thread(new Runnable() {

            

            @Override

            public void run() {

                 while(true){

                     try {

                        Thread.sleep(200) ;

                        out.print("zhangsan") ;

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                 }

            }

        }).start();

        

        

        new Thread(new Runnable() {

                    

                    @Override

                    public void run() {

                         while(true){

                             try {

                                Thread.sleep(1000) ;

                                out.print("liaokailinliaokailinliaokailinliaokailinliaokailinliaokailin") ;

                            } catch (InterruptedException e) {

                                e.printStackTrace();

                            }

                         }

                    }

                }).start();

    }

    

    

    

}





class Outputter{

    Lock lock = new ReentrantLock() ;

    public void print(String name){

        lock.lock() ; //加上锁  只有等到操作全完成以后才释放锁

        try {

            if(name!=null){

                for(int i = 0 ; i<name.length() ;i++){

                    System.out.print(name.charAt(i));

                }

                System.out.println();

            }

        }finally {

            lock.unlock() ;//解锁 一般都在finally中解锁  不过程序是否有异常 最终都要解锁 否则会导致阻塞

        }

    }

}

 

    

3. 读写锁

     读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;

如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!

package cn.itcast.heima2;



import java.util.Random;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;



public class ReadWriteLockTest {

    public static void main(String[] args) {

        final Queue3 q3 = new Queue3();

        for(int i=0;i<3;i++)

        {

            new Thread(){

                public void run(){

                    while(true){

                        q3.get();                        

                    }

                }

                

            }.start();



            new Thread(){

                public void run(){

                    while(true){

                        q3.put(new Random().nextInt(10000));

                    }

                }            

                

            }.start();

        }

        

    }

}



class Queue3{

    private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。

    ReadWriteLock rwl = new ReentrantReadWriteLock();

    public void get(){

        rwl.readLock().lock();

        try {

            System.out.println(Thread.currentThread().getName() + " be ready to read data!");

            Thread.sleep((long)(Math.random()*1000));

            System.out.println(Thread.currentThread().getName() + "have read data :" + data);            

        } catch (InterruptedException e) {

            e.printStackTrace();

        }finally{

            rwl.readLock().unlock();

        }

    }

    

    public void put(Object data){



        rwl.writeLock().lock();

        try {

            System.out.println(Thread.currentThread().getName() + " be ready to write data!");                    

            Thread.sleep((long)(Math.random()*1000));

            this.data = data;        

            System.out.println(Thread.currentThread().getName() + " have write data: " + data);                    

        } catch (InterruptedException e) {

            e.printStackTrace();

        }finally{

            rwl.writeLock().unlock();

        }

        

    

    }

}

 

4. Condition

 

package org.lkl.thead.foo01;



import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;



public class ConditionFoo {

    /**

     * 子线程先执行10次 然后主线程再执行20次 如此循环50次

     */

    public static void main(String[] args) {

    final Business b = new Business() ;

        //子线程执行50次

        for(int i = 1 ;i<=50 ;i++){

            final int seq = i ;

            new Thread(new Runnable() {

                

                public void run() {

                    b.sub(seq) ;

                }

            }).start() ;

        }

        

        //主线程执行50次

        for(int i = 1 ;i<=50 ;i++){

               b.main(i) ;         

        }

        

    }

    

    

}



class Business{

    boolean isSub =  true ;

    

    Lock lock = new ReentrantLock() ;

    Condition condition = lock.newCondition() ;

    //子线程执行10次

    public  void sub(int j ){  //加lock以后不需要synchronized

        lock.lock() ;

        try {

            while(!isSub){

                try {

                    condition.await() ;

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

            for(int i = 1 ;i<=10 ;i++){

                System.out.println("sub thread execute times " + i  + " loop of "+ j);

            }

            

            isSub = false ;

            condition.signalAll() ;

        } finally {

            lock.unlock() ;

        }

        

    }

    

    

    //主线程执行20次

    public  void main(int j ){

        lock.lock() ;

        try {

            while(isSub){

                try {

                    condition.await() ;

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

            for(int i = 1 ;i<=20 ;i++){

                System.out.println("main thread execute times " + i  + " loop of "+ j);

            }

            

            isSub = true ;

        //    condition.signal() ;

            condition.signalAll() ;

        }finally {

            lock.unlock() ;

        }

    }

}

 

 

 5. 通过condition实现三个线程之间的通信

package cn.itcast.heima2;



import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;



public class ThreeConditionCommunication {



    /**

     * @param args

     */

    public static void main(String[] args) {

        

        final Business business = new Business();

        new Thread(

                new Runnable() {

                    

                    @Override

                    public void run() {

                    

                        for(int i=1;i<=50;i++){

                            business.sub2(i);

                        }

                        

                    }

                }

        ).start();

        

        new Thread(

                new Runnable() {

                    

                    @Override

                    public void run() {

                    

                        for(int i=1;i<=50;i++){

                            business.sub3(i);

                        }

                        

                    }

                }

        ).start();        

        

        for(int i=1;i<=50;i++){

            business.main(i);

        }

        

    }



    static class Business {

            Lock lock = new ReentrantLock();

            Condition condition1 = lock.newCondition();

            Condition condition2 = lock.newCondition();

            Condition condition3 = lock.newCondition();

          private int shouldSub = 1;

          public  void sub2(int i){

              lock.lock();

              try{

                  while(shouldSub != 2){

                      try {

                        condition2.await();

                    } catch (Exception e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                  }

                    for(int j=1;j<=10;j++){

                        System.out.println("sub2 thread sequence of " + j + ",loop of " + i);

                    }

                  shouldSub = 3;

                  condition3.signal();

              }finally{

                  lock.unlock();

              }

          }



          public  void sub3(int i){

              lock.lock();

              try{

                  while(shouldSub != 3){

                      try {

                        condition3.await();

                    } catch (Exception e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                  }

                    for(int j=1;j<=20;j++){

                        System.out.println("sub3 thread sequence of " + j + ",loop of " + i);

                    }

                  shouldSub = 1;

                  condition1.signal();

              }finally{

                  lock.unlock();

              }

          }          

          

          public  void main(int i){

              lock.lock();

              try{

                 while(shouldSub != 1){

                          try {

                            condition1.await();

                        } catch (Exception e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                        }

                      }

                    for(int j=1;j<=100;j++){

                        System.out.println("main thread sequence of " + j + ",loop of " + i);

                    }

                    shouldSub = 2;

                    condition2.signal();

          }finally{

              lock.unlock();

          }

      }

    

    }

}

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Condition)