夜光序言:
我都舍不得欺负的人,哪能让别人欺负?
正文:
以道御术 / 以术识道
package 深入理解volatile原理与使用;
//保证可见性的前提
//多个线程拿到的是同一把锁,否则是保证不了的
public class Demo {
//volatile保证线程的一致性
public volatile int a = 1; //变量上面加上一个volatile
public synchronized int getA() { //这里加上一把锁
return a;
}
public synchronized void setA(int a) { //这里加上一把锁
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.a = a;
}
//一个线程在get,另外一个线程在set,很大情况下会出现线程安全问题
public static void main(String[] args) {
//我们先new一个对象出来
Demo d = new Demo();
d.a = 10;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.a);
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终的结果为:" + d.getA());
}
}
package 深入理解volatile原理与使用;
public class Demo2 {
//volatile关键词保证一下
public volatile boolean run = false;
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=1;i<=10;i++){
System.err.println("执行了第" + i + "次");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
demo2.run = true;
}
}).start();
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
while(!demo2.run){
//不执行
}
System.err.println("线程2执行了~~");
}
})
.start();
}
}
package Lock接口认识和使用;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//夜光
public class Sequence {
private int value;
Lock lock = new ReentrantLock(); //使用这个就可以了
public int getNext(){ //相当于一个门,加一把锁
lock.lock();
int a = value++;
lock.unlock(); //释放锁
return value++;
}
public static void main(String[] args) {
//我们调用的时候
// new Sequence().getNext();
//1. 下面这种方式面对多线程,会出现不可预期的问题
// Sequence s = new Sequence();
// while(true){ //多次调用
// System.out.println(s.getNext());
// }
//2. 我们看看下面这种方式
Sequence s = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
//下面,我们不停地去调用生成器
while (true){
System.out.println(Thread.currentThread().getName()
+""+s.getNext());
try {
Thread.sleep(1000); //休息一会儿
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//然后,我们重写多个
//嗯唔
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
//下面,我们不停地去调用生成器
while (true){
System.out.println(Thread.currentThread().getName()
+""+s.getNext());
try {
Thread.sleep(1000); //休息一会儿
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//第三个线程
new Thread(new Runnable() {
@Override
public void run() {
//下面,我们不停地去调用生成器
while (true){
System.out.println(Thread.currentThread().getName()
+""+s.getNext());
try {
Thread.sleep(1000); //休息一会儿
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
package 自旋锁死锁重入锁.可重入锁;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class MyLock implements Lock {
//怎么判断第一个哈
private boolean isLocked = false;
@Override
public synchronized void lock() { //我们加上这个关键词,进来的线程要等待
while (isLocked) //只要为true,就~
//.....
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
isLocked = true;
}
//第一个资源执行完毕,需要释放锁
//那么我们则
@Override
public synchronized void unlock() { //synchronized必须要加上这个
isLocked = false;
notify();
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public Condition newCondition() {
return null;
}
}
package 自旋锁死锁重入锁.可重入锁;
//Sequence,我们写一个这个
public class Sequence {
private MyLock lock = new MyLock(); //我们先构建一下~
private int value;
public int getNext(){
lock.lock();
value++;
lock.unlock();
return value;
}
public static void main(String[] args) {
Sequence s = new Sequence();
//现在,我们进行一下测试,夜光:三个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(s.getNext());
}
}).start();
}
}
上面表示不可重入
那么下面,我们改成可重入的
可重入的锁,需要记住当下的线程
package 自旋锁死锁重入锁.可重入锁;
//我们说这个锁是可以重入的,我们来写一个例子
public class Demo {
MyLock lock = new MyLock();
public void a(){
lock.lock();
System.out.println("a");
//这里,我们调用b方法
b();
lock.unlock();
}
public void b(){
lock.lock();
System.out.println("b");
lock.unlock();
}
//然后,我们来测试
public static void main(String[] args) {
Demo d = new Demo();
//然后,我们来创建线程
//嗯唔
//我们只要调用a就可以了,因为a里面包含了b
new Thread(new Runnable() {
@Override
public void run() {
d.a();
}
}).start();
// new Thread(new Runnable() {
// @Override
// public void run() {
// d.b();
// }
// }).start();
}
}
package 自旋锁死锁重入锁.可重入锁;
//Sequence,我们写一个这个
public class Sequence {
private MyLock lock = new MyLock(); //我们先构建一下~
private int value;
public int getNext(){
lock.lock();
value++;
lock.unlock();
return value;
}
public static void main(String[] args) {
Sequence s = new Sequence();
//现在,我们进行一下测试,夜光:三个线程
new Thread(new Runnable() {
@Override
public void run() {
while (true)
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) //我们加上一个这个
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true)
System.out.println(s.getNext());
}
}).start();
}
}
package 自旋锁死锁重入锁.可重入锁;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class MyLock implements Lock {
//怎么判断第一个哈
private boolean isLocked = false;
//为了实现可重入锁
//我们进行必要的改造
//首先,需要记住当下的线程
private Thread lockBy = null; //有点帅
//锁的数量
private int lockCount = 0;
@Override
public synchronized void lock() { //我们加上这个关键词,进来的线程要等待
Thread currentThread = Thread.currentThread();//嗯唔
while (isLocked && currentThread != lockBy) //只要为true,就~
//.....
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
isLocked = true;
lockBy = currentThread;
lockCount++; //递增
}
//第一个资源执行完毕,需要释放锁
//那么我们则
@Override
public synchronized void unlock() { //synchronized必须要加上这个
if (lockBy == Thread.currentThread()){ //如果是相等的
lockCount--;
if (lockCount == 0){
notify();
isLocked = false;
}
}
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public Condition newCondition() {
return null;
}
}