呃,多线程还有设计模式啊,我只听说过23种设计模式
什么是设计模式,设计模式感觉就像是一个编程手法,一种前辈总结出来的编程技巧精华,就比如学了java的基本语法,学了web,进行web后端开发,好像就可以随便开发一个controller、service 、dao 好像有那么点设计模式的味道,但是这都是框架开发约定俗称的基本代码结构规范,等业务量复杂起来,类之间的关系,对象之间的关系,的各种组合形形色色,为了软件开发的基本准则,前人总结大量开发经验形成了23中不通业务场景下的设计技巧。在学习这些设计模式的前提就是多javase语法足够熟练,对面向对象的特征足够熟练于心,有自己的理解,那么你就会发现,设计模式感觉就是玩的是类与类,对象与对象之间的关系。
同样的道理,对于多线程编程来说,难道我们知道怎么创建一个线程出来就可以了吗? 同样的道理,如果要写出来一个好的多线程,必须的学习多线程设计模式的编程技巧,同样在学习多线程设计模式之前,得对线程足够了解,最起码,线程的api方法的背后做的是什么,已经线程之间如果同步。
JUC下无处不是多线程设计模式的运用。
单线程执行设计模式
单线程设计模式就是某个代码块只能允许线程一个一个的通过,也是线程之间的同步 。
为啥要一个一个的通过,说白就是这个同步代码块里面有共享变量,会产生线程的安全问题
设计一道门, 原则是一个门只能一个人过:
/**
* 安全门
* @Author: puhaiguo
* @Date: 2022-07-09 21:41
* @Version 1.0
*/
public class SafeDoor {
private String aliasOne;
private String aliasTwo;
private int count = 0 ;
public SafeDoor() {
}
public void how(String aliasOne, String aliasTwo){
this.aliasOne = aliasOne;
this.aliasTwo = aliasTwo;
}
public void passDoor(){
count++;
if (!aliasOne.substring(0, 1).equals(aliasTwo.substring(0, 1))){
System.out.println(count + " ========ERROR======== " + aliasOne + " " + aliasTwo);
}
}
}
测试类:
/**
* 测试安全门
* @Author: puhaiguo
* @Date: 2022-07-09 21:46
* @Version 1.0
*/
public class TestSafeDoor {
public static void main(String[] args) {
SafeDoor safeDoor = new SafeDoor();
new Thread(()->{
while (true){
safeDoor.how("xiaoming", "xiaodong");
safeDoor.passDoor();
}
}).start();
new Thread(()->{
while (true){
safeDoor.how("ming", "mong");
safeDoor.passDoor();
}
}).start();
}
}
结果:
🆗 加同步代码块:
/**
* 测试安全门
* @Author: puhaiguo
* @Date: 2022-07-09 21:46
* @Version 1.0
*/
public class TestSafeDoor {
public static void main(String[] args) {
SafeDoor safeDoor = new SafeDoor();
new Thread(()->{
while (true){
synchronized (safeDoor){
safeDoor.how("xiaoming", "xiaodong");
safeDoor.passDoor();
}
}
}).start();
new Thread(()->{
while (true){
synchronized (safeDoor){
safeDoor.how("ming", "mong");
safeDoor.passDoor();
}
}
}).start();
}
}
synchrozed 实现的是互斥同步
扩展点: 有时候的需求就是同步代码快同一个可以允许最多n个线程同时通过
分析:得有一个标记为代表线程的允许上限个数,还有一个记录当前线程的个数
记录当前线程的个数是多个线程来修改的所以需要进行同步安全;
/**
* 自己实现semphore
* @Author: puhaiguo
* @Date: 2022-07-09 22:25
* @Version 1.0
*/
public class MySemphore {
/*线程数的上线*/
private int topCount = 0;
/*记录当前线程数*/
private int curCount = 0;
/*互斥锁*/
private Object monitor = new Object();
public MySemphore(int topCount) {
this.topCount = topCount;
}
public void enter(){
synchronized (monitor){
try {
if (curCount == topCount){
monitor.wait();
}
curCount++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void quit(){
synchronized (monitor){
curCount--;
monitor.notify();
}
}
}
测试:
/**
* 测试我的信号量
* @Author: puhaiguo
* @Date: 2022-07-09 22:31
* @Version 1.0
*/
public class TestMySemphore {
/*一次允许10个*/
static MySemphore mySemphore = new MySemphore(10);
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
int finalI = i;
new Thread(()-> toHappy(finalI)).start();
}
}
public static void toHappy(int i){
try {
mySemphore.enter();
System.out.println(i + " come in for happer");
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mySemphore.quit();
}
}
}