JUC的各种同步锁

Atomic** 类

      采用的是CAS方式

LongAdder类

    采用的是分段锁

package juc.lock;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

public class AtomicVSSynchronized {
	static long count1 = 0;
	static AtomicInteger count2 = new AtomicInteger(0);
	static LongAdder count3 =new LongAdder();
	public static void main(String[] args) throws InterruptedException {
		Thread[] threads = new Thread[1000];
		for(int i = 0; i< threads.length; i++)
			threads[i] = new Thread(()->  {
				for(int j = 0; j < 1000; j++)
					count2.incrementAndGet();
			});
		long start = System.currentTimeMillis();
		for(Thread thread:threads) thread.start();
		for(Thread thread:threads) thread.join();
		long end = System.currentTimeMillis();
		System.out.println("Atmic**:"+ (end - start));
		
		/
		Object lock = new Object();
		for(int i =0; i< threads.length; i++)
			threads[i] = new Thread(new Runnable() {

				@Override
				public void run() {
					for(int i = 0 ; i< 1000; i++)
						synchronized(lock) {
							count1++;
						};
					
				}
				
				
			});
		start = System.currentTimeMillis();
		for(Thread thread:threads) thread.start();
		for(Thread thread:threads) thread.join();
		end = System.currentTimeMillis();
		System.out.println("Synchronized**:"+ (end - start));
		/
		for(int i = 0; i< threads.length; i++)
			threads[i] = new Thread(()->  {
				for(int j = 0; j < 1000; j++)
					count3.increment();
			});
		start = System.currentTimeMillis();
		for(Thread thread:threads) thread.start();
		for(Thread thread:threads) thread.join();
		end = System.currentTimeMillis();
		System.out.println("Atmic**:"+ (end - start));
		
	}
}

如果线程数多的情况下,可能LongAdder的速度会快些. LongAdder采用的是把不同的线程进行分组,最后再进行统计加和,当然每个线程采用的还是CAS的方式。

ReentrantLock

有以下的特性

  •  公平与不公平锁, 可以规定是fair还是不fair。公平锁的话,每个线程都拿到这个锁的概率都是公平的,进入同一段代码的概率都是一致的。默认是非公平锁。
  • package juc.lock;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ReentrantLOCK_FAIR implements Runnable {
    	static ReentrantLock lock = new ReentrantLock(true);
    	public void run() {
    		for(int i = 0;i < 100;i++)
    		{
    			lock.lock();
    		    try {
    		    	System.out.println(Thread.currentThread().getName());
    		    }finally {
    			lock.unlock();
    		    }
    		}
    		
    	}
    	public static void main(String[] args) 
    	{
    		ReentrantLOCK_FAIR r1 = new ReentrantLOCK_FAIR();
    		Thread t1 =new Thread(r1);
    		Thread t2 =new Thread(r1);
    		t1.start();
    		t2.start();
    	}
    
    }
    

     

  •  
  • trylock
  • lockInterruptibly

reentrantLock 和synchronized的不同

1. 底层实现,reentrantLock是使用CAS, synchronized是使用系统锁

2. synchronized不需要手动锁和解锁,reentrantLock需要手动调用锁和解锁

3. reentrantLock有一些特殊的接口,synchronized没有

CountDownLatch

  • 和join很像。每个线程执行一次,对latch减一,当为零的时候,latch就打开了。
  • package juc.lock;
    
    import java.util.concurrent.CountDownLatch;
    
    public class UsingCountDown {
    
    	 public void usingCountDown() {
    		 Thread[] threads = new Thread[100];
    		 CountDownLatch latch = new CountDownLatch(threads.length);
    		 for(int i = 0 ; i < threads.length; i++)
    		 {
    			 threads[i] = new Thread(()->{
    				 int result = 0;
    				 for(int j = 0 ; j < 10000; j++ ) result+=1;
    				 latch.countDown();
    			 });
    		 }
    		 try {
    			latch.await();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		 for(int i = 0 ; i< threads.length;i++)
    			 threads[i].start();
    		 System.out.println("end latch");
    		 		 
    	 }
    }
    

     

  • CyclicBarrier

比如有一个任务要等待好几个任务都结束才能跑,就可以用这个接口。

  • package juc.lock;
    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    public class TestCyclicBarrier {
           public static void main(String[] args) {
        	   CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() {
        		   public void run() {
        			   System.out.println("满人,发车");
        		   }
        	   });
        	   for(int i = 0 ; i< 100;i++) {
        		   new Thread(()->{
        			   try {
    					barrier.await();
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (BrokenBarrierException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
        		   }).start(); 
        	   }
        	   
           }
    }
    

    ReentrantReadWriteLock

  • ReadLock 允许读的线程进来,但是不允许写的线程进来。同样,WriteLock不允许任何别的线程进来
  • package juc.lock;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class TestReadWriteLock {
            static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
            static int value = 0;
            static Lock readl = readWriteLock.readLock();
            static Lock writel = readWriteLock.writeLock();
            public static void read(Lock lock)
            {
            	
            	try {
            		lock.lock();
    				Thread.sleep(1000);
    				System.out.println("read over");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
            	finally {
            		lock.unlock();
            	}
            	
            }
            public static void write(Lock lock,int v) {
            	
            	try {
            		lock.lock();
            		value =v;
    				Thread.sleep(1);
    				System.out.println("write over");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
            	finally {
            		lock.unlock();
            	}
            	
            	
            }
            public static void main(String[] args) {
            	Runnable readR = ()-> read(readl);
            	Runnable writeR = ()-> write(writel,2);
            	for(int i =0 ; i < 12; i++)
            	{
            		new Thread(readR).start() ;
            	}
            	for(int i =0 ; i < 2; i++)
            	{
            		new Thread(writeR).start() ;
            	}
            }
    }
    

     

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值