对于用volatile修饰的变量,JVM虚拟机只是保证从主内存加载到线程工作内存的值是最新的,例如线程1和线程2在进行read和load的操作中,发现主内存中count的值都是5,那么都会加载这个最新的值。也就是说,volatile关键字解决的是变量读时的可见性问题 ,但无法保证原子性,对于多个线程访问同一个实例变量还是需要加锁同步。
atomic 是 jdk 的扩展类,保证 变量的原子性。
这个有待实践,测试的时候三个线程 synchronized 要快于 lock ,并发量 大的时候 网上说 lock 要更好,这个需要实践。
- 多线程共享问题 关于 volatile 关键字共享问题 ?
- lock 和 synchronized 性能对比?
- 关于 用线程池和线程裸奔的性能问题?
线程池 测试三个线程 快于 裸奔
demo 实例:
package com.example.demo; import org.junit.Test; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Author: joker * @Date: 2019/7/2 0002 14:08 */ public class LockTest { // lock():获取锁,如果锁被暂用则一直等待 // // unlock():释放锁 // // tryLock(): 注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true // // tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间 // // lockInterruptibly():用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事 private static Lock lock = new ReentrantLock(); static AtomicInteger flag=new AtomicInteger(0); static long startTime=0L; static long endTime=0L; //需要参与同步的方法 private static void method(Thread thread){ for(byte i=0;i<50;i++){ if(i==0){ startTime=System.currentTimeMillis(); } //lock.lock(); try { if(thread.getName().equals("t1")){ System.out.println("线程名================>"+thread.getName() + "获得了锁"+(flag.getAndIncrement())); }else { System.out.println("线程名"+thread.getName() + "获得了锁"+(flag.getAndIncrement())); } if(flag.get()==150){ System.out.println("========>执行时间" +(System.currentTimeMillis()-startTime)); } }catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); } finally { // System.out.println("线程名"+thread.getName() + "释放了锁"); //lock.unlock(); } } } // @Test public static void main(String[] args) { LockTest lockTest = new LockTest(); // System.out.println("执行了多少次========》"+i); //线程1 ExecutorService cachedThreadPool = Executors.newFixedThreadPool(2); Thread t1 = new Thread(new Runnable() { @Override public void run() { method(Thread.currentThread()); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { method(Thread.currentThread()); } }, "t2"); Thread t3 = new Thread(new Runnable() { @Override public void run() { method(Thread.currentThread()); } }, "t3"); long _startTime= System.currentTimeMillis(); /* t2.start(); t1.start(); t3.start();*/ // long _endTime= System.currentTimeMillis(); // // System.out.println("======> 执行结束时间"+(_endTime-_startTime)); // // System.out.println(t1.getState()); // System.out.println(t2.getState()); cachedThreadPool.submit(t1); cachedThreadPool.submit(t2); cachedThreadPool.submit(t3); // for (byte i=0;i<30;i++){ // // } } }