高级特性
指令重排
public class HappenBefore {
//变量1
private static int a = 0;
//变量2
private static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<10;i++) {
a = 0;
flag = false;
//线程1 更改数据
Thread t1 = new Thread(()->{
a = 1;
flag = true;
}) ;
//线程2 读取数据
Thread t2 = new Thread(()->{
if(flag) {
a *=1;
}
//指令重排
if(a == 0) {
System.out.println("happen before a->"+a);
}
}) ;
t1.start();
t2.start();
//合并线程
t1.join();
t2.join();
}
}
}
volatile
/**
* volatile用于保证数据的同步,也就是可见性
*
* @author 裴新 QQ:3401997271
*
*/
public class VolatileTest {
private volatile static int num = 0;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while(num==0) { //此处不要编写代码
}
}) .start();
Thread.sleep(1000);
num = 1;
}
}
DCL单例模式
package com.sxt.others;
/**
* DCL单例模式: 懒汉式套路基础上加入并发控制,保证在多线程环境下,对外存在一个对象
* 1、构造器私有化 -->避免外部new构造器
* 2、提供私有的静态属性 -->存储对象的地址
* 3、提供公共的静态方法 --> 获取属性
*
* @author 裴新 QQ:3401997271
*
*/
public class DoubleCheckedLocking {
//2、提供私有的静态属性
//没有volatile其他线程可能访问一个没有初始化的对象
private static volatile DoubleCheckedLocking instance;
//1、构造器私有化
private DoubleCheckedLocking() {
}
//3、提供公共的静态方法 --> 获取属性
public static DoubleCheckedLocking getInstance() {
//再次检测
if(null!=instance) { //避免不必要的同步 ,已经存在对象
return instance;
}
synchronized(DoubleCheckedLocking.class) {
if(null == instance) {
instance = new DoubleCheckedLocking();
//1、开辟空间 //2、初始化对象信息 //3、返回对象的地址给引用
}
}
return instance;
}
public static DoubleCheckedLocking getInstance1(long time) {
if(null == instance) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new DoubleCheckedLocking();
//1、开辟空间 //2、初始化对象信息 //3、返回对象的地址给引用
}
return instance;
}
public static void main(String[] args) {
Thread t = new Thread(()->{
System.out.println(DoubleCheckedLocking.getInstance());
}) ;
t.start();
System.out.println(DoubleCheckedLocking.getInstance());
}
}
ThreadLocal
/**
* ThreadLocal:每个线程自身的存储本地、局部区域
* get/set/initialValue
* @author 裴新 QQ:3401997271
*
*/
public class ThreadLocalTest01 {
//private static ThreadLocal<Integer> threadLocal = new ThreadLocal<> ();
//更改初始化值
/*private static ThreadLocal<Integer> threadLocal = new ThreadLocal<> () {
protected Integer initialValue() {
return 200;
};
};*/
private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 200);
public static void main(String[] args) {
//获取值
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
//设置值
threadLocal.set(99);
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
new Thread(new MyRun()).start();
new Thread(new MyRun()).start();
}
public static class MyRun implements Runnable{
public void run() {
threadLocal.set((int)(Math.random()*99));
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
}
}
}
/**
* ThreadLocal:每个线程自身的数据,更改不会影响其他线程
* @author 裴新 QQ:3401997271
*
*/
public class ThreadLocalTest02 {
private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 1);
public static void main(String[] args) {
for(int i=0;i<5;i++) {
new Thread(new MyRun()).start();
}
}
public static class MyRun implements Runnable{
public void run() {
Integer left =threadLocal.get();
System.out.println(Thread.currentThread().getName()+"得到了-->"+left);
threadLocal.set(left -1);
System.out.println(Thread.currentThread().getName()+"还剩下-->"+threadLocal.get());
}
}
}
/**
* ThreadLocal:分析上下文 环境 起点
* 1、构造器: 哪里调用 就属于哪里 找线程体
* 2、run方法:本线程自身的
* @author 裴新 QQ:3401997271
*
*/
public class ThreadLocalTest03 {
private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 1);
public static void main(String[] args) {
new Thread(new MyRun()).start();
new Thread(new MyRun()).start();
}
public static class MyRun implements Runnable{
public MyRun() {
threadLocal.set(-100);
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
}
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
//new Thread(new MyRunxxx()).start();
}
}
}
/**
* InheritableThreadLocal:继承上下文 环境的数据 ,拷贝一份给子线程
* @author 裴新 QQ:3401997271
*
*/
public class ThreadLocalTest04 {
private static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();
public static void main(String[] args) {
threadLocal.set(2);
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
//线程由main线程开辟
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
threadLocal.set(200);
System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());
}) .start();
}
}
可重入锁
package com.sxt.others;
/**
* 可重入锁: 锁可以延续使用 + 计数器
*
* @author 裴新 QQ:3401997271
*
*/
public class LockTest03 {
ReLock lock = new ReLock();
public void a() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
doSomething();
lock.unlock();
System.out.println(lock.getHoldCount());
}
//不可重入
public void doSomething() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
//...................
lock.unlock();
System.out.println(lock.getHoldCount());
}
public static void main(String[] args) throws InterruptedException {
LockTest03 test = new LockTest03();
test.a();
Thread.sleep(1000);
System.out.println(test.lock.getHoldCount());
}
}
// 可重入锁
class ReLock{
//是否占用
private boolean isLocked = false;
private Thread lockedBy = null; //存储线程
private int holdCount = 0;
//使用锁
public synchronized void lock() throws InterruptedException {
Thread t = Thread.currentThread();
while(isLocked && lockedBy != t) {
wait();
}
isLocked = true;
lockedBy = t;
holdCount ++;
}
//释放锁
public synchronized void unlock() {
if(Thread.currentThread() == lockedBy) {
holdCount --;
if(holdCount ==0) {
isLocked = false;
notify();
lockedBy = null;
}
}
}
public int getHoldCount() {
return holdCount;
}
}
CAS
import java.util.concurrent.atomic.AtomicInteger;
/**
* CAS:比较并交换
*
* @author 裴新 QQ:3401997271
*
*/
public class CAS {
//库存
private static AtomicInteger stock = new AtomicInteger(5);
public static void main(String[] args) {
for(int i=0;i<5;i++) {
new Thread(()->{
//模拟网络延时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer left = stock.decrementAndGet();
if(left<1) {
System.out.println("抢完了...");
return ;
}
System.out.print(Thread.currentThread().getName()+"抢了一件商品");
System.out.println("-->还剩"+left);
}) .start();
}
}
}