本文共 8829 字,大约阅读时间需要 29 分钟。
package com.myd.cn; /** * * @author dymll * * @date 2014/3/25 * * */ public class ThreadSharedVariables { private static int sharedVar = 0; public static void main(String[] args) { Thread threadA = new Thread(()->{ System.out.println(Thread.currentThread().getName()+" sharedVar = "+sharedVar); sharedVar = 1; System.out.println(Thread.currentThread().getName()+" sharedVar = "+sharedVar); },"ThreadA"); Thread threadB = new Thread(()->{ System.out.println(Thread.currentThread().getName()+" sharedVar = "+sharedVar); sharedVar = 1; System.out.println(Thread.currentThread().getName()+" sharedVar = "+sharedVar); },"ThreadB"); threadA.start(); / /线程B启动后,获取的值认为0,说明线程间共享变量还没等线程A在CPU缓存中修改后写入到主内存,就被线程B读取了,造成脏读 threadB.start(); }}
package com.myd.cn;public class ThreadCommandReorder { private static int a = 0; private static int b = 0; private static int x = 0; private static int y = 0; public static void main(String[] args) throws InterruptedException { Thread threadA = new Thread(()->{ b = 1; x = a; },"threadA"); Thread threadB = new Thread(()->{ a = 1; y = b; },"threadB"); threadA.start(); threadB.start(); //等待ThreadA执行完后,主线程才往下继续执行 threadA.join(); //等待ThreadB执行完后,主线程才往下继续执行 threadB.join(); //此时因为JVM指令编译会对指令进行优化,可能会发生指令重排,而出现错误的赋值,如x = 1 ; y = 0 //合理输出应是 x=1,y=1 System.out.println("x = "+x+" ; y = "+y); }}
package com.myd.cn;import java.util.concurrent.Executor;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class SynchronizedSellTicket { private static int totalTickets = 10000; private static final Object LOCK = new Object(); public static void main(String[] args) { sellTickets(); } /** * 通过启动线程池,向线程池提交任务,有线程池调度线程执行任务 **/ private static void sellTickets(){ ExecutorService executorService = Executors.newFixedThreadPool(2); Runnable runnableA = ()->{ i nt threadAtickets = 0 ; //如果不低于1张票 while (sellTicketsWithSynchronizedObject(1)) { threadAtickets ++; } System.out.println("程序A卖出火车票: "+threadAtickets); }; Runnable runnableB = ()->{ int threadBtickets = 0 ; //如果不低于1张票 while (sellTicketsWithSynchronizedObject(1)) { threadBtickets ++; } System.out.println("程序B卖出火车票: "+threadBtickets); }; //提交两个卖票程序 executorService.submit(runnableA); executorService.submit(runnableB); } /** * 在方法加锁,进行买票,保证票不卖超 * @param count * @return * */ private static synchronized boolean sellTicketsWithSyncMethod(int count) { //如果要卖票数小于剩余票数,则不买,退出卖票流程 if(totalTickets - count < 0){ r eturn false; }else{ //否则进入卖票流程 totalTickets = totalTickets - count ; return true; } } /** * 在对象加锁,降低锁的作用范围,提高并发量 * * @param count * */ private static boolean sellTicketsWithSynchronizedObject(int count) { synchronized (LOCK) { //计算总票数减去申请票数的差值 int flag = totalTickets - count; //如果为负数,则表明总票数不够申请票数,不进行售卖 if(flag < 0){ return false; }else{ totalTickets = totalTickets - count; return true; } } }}
javap -c -p -v SynchronizedSellTicket.class
synchronized方法
1.代码package com.myd.cn; public class CheckSynchronizedOnDiffObj { public static synchronized void staticSynchronized() throws InterruptedException{ System.out.println(Thread.currentThread().getName()+" is Sleeping"); Thread.sleep(1000L); System.out.println(Thread.currentThread().getName()+" finished Sleeping");} public static void main(String[] args) { new Thread(()->{ try { CheckSynchronizedOnDiffObj.staticSynchronized(); } catch (InterruptedException e) { e.printStackTrace(); } },"thread1").start();; new Thread(()->{ try { CheckSynchronizedOnDiffObj.staticSynchronized(); } catch (InterruptedException e) { e.printStackTrace(); } },"thread2").start(); }} 2.执行结果,串行执行的 thread1 is Sleeping thread1 finished Sleeping thread2 is Sleeping thread2 finished Sleeping
若是作用在实例方法,锁作用在类的实例上,类实例级别是可以同时执行
package com.myd.cn; public class CheckSynchronizedOnDiffObj { public synchronized void ObjSysnchronized() throws InterruptedException { System.out.println(Thread.currentThread().getName()+" is Sleeping"); Thread.sleep(1000L); System.out.println(Thread.currentThread().getName()+" finished Sleeping"); } public static void main(String[] args) { CheckSynchronizedOnDiffObj check1 = new CheckSynchronizedOnDiffObj(); CheckSynchronizedOnDiffObj check2 = new CheckSynchronizedOnDiffObj(); new Thread(()->{ try { check1.ObjSysnchronized(); } catch (InterruptedException e) { e.printStackTrace(); } },"thread1").start();; new Thread(()->{ try { check2.ObjSysnchronized(); } catch (InterruptedException e) { e.printStackTrace(); } },"thread2").start(); }} 2.结果,并行输出thread1 is Sleepingthread2 is Sleepingthread2 finished Sleepingthread1 finished Sleeping
synchronized代码块
package com.myd.cn; import java.util.concurrent.locks.ReentrantLock; public class SynchronizedAndReentrantLock { private static Object LOCK = new Object(); private static void reetrant(){ synchronized (LOCK) { System.out.println("持有当前锁"); synchronized(LOCK){ System.out.println(" 再次持有锁"); } } } /** * 使用默认非公平(可实现公平)的可重入排它锁 * 可以添加获取锁的等待时间(超时不进行等待),也可不指定超时时间 */ private static void useReentrantLock(){ ReentrantLock lock = new ReentrantLock(); try { //获取后,一定在finally代码块进行释放 lock.lock(); System.out.println("持有当前锁"); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public static void main(String[] args) { //reetrant(); useReentrantLock(); } }
1.都是用于多线程中对资源加锁,控制代码同一时间只有单线程在执行2.当一个线程获取了锁,其他线程均需要阻塞等待3.均为可重入锁
1.实现层次 Synchronzied是JVM级别实现的同步机制,由JVM字节码实现,以前并发量比较时,稍逊于ReentrantLock,但是随着JDK对其不断优化,一般场景下由于 ReentrantLockReentrantLock是代码层面实现的锁机制,获取可以设置超时时间,使用完毕后一定要释放。Synchronized无法设置超时时间,但是在获取锁后,使用完毕无需手动释放锁资源2.中断等待: 获取到Synchronized的线程如果因为外部原因(I/O,网络)等时阻塞,无法处理其他业务 Reentrant在进行中断等待时,可以处理其他业务,进而提高并发量,适用于高竞态的并发场景3.锁的公平性 ReentrantLock实现了非公平锁(默认)和公平锁(实例化传参为true) synchronized 只有非公平锁
package com.myd.cn.volatileDemo; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class VolatileSence { //保证线程间共享变量的可见性,修改可以及时通知到其他线程 private volatile boolean isFinished = false; public void finish(){ isFinished = true; } public void work(){ //当为true时,退出while循环 while (!isFinished) { //working System.out.println("i'm working"); } }}
package com.myd.cn.volatileDemo; public class Singleton { //用时申请,减少开销,提供加载速度 private static volatile Singleton singleton; //私有化构造器 private Singleton(){ } //使用double check,减少同步代码块的作用范围 public static Singleton getSingleton(){ if(null == singleton){ //同步机制作用在类上 synchronized (Singleton.class) { if(null == singleton){ singleton = new Singleton(); } } } return singleton; }}
synchronzied和volatile区别
转载地址:http://jhjzb.baihongyu.com/