当前位置: 首页 > news >正文

如何把网站做在百度小程序内58同城安居客

如何把网站做在百度小程序内,58同城安居客,网站建设控制,做网站制作利润有多少大家新年快乐呀,今天是第三期啦,大家前几期的内容掌握的怎么样啦? 1,线程死锁 1.1 构成死锁的场景 a)一个线程一把锁 这个在java中是不会发生的,因为我们之前讲的可重入机制,在其他语言中可…

大家新年快乐呀,今天是第三期啦,大家前几期的内容掌握的怎么样啦?

1,线程死锁 

1.1 构成死锁的场景

a)一个线程一把锁

这个在java中是不会发生的,因为我们之前讲的可重入机制,在其他语言中可能会发生的;

public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(()->{synchronized (locker){synchronized (locker){System.out.println(1111);}}});t1.start();t1.join();System.out.println("main");}

按理来说,t1线程刚进synchronized就获取到了锁对象,就要保持,进入第二个synchronized就要请求第一个锁对象,第一个要保持不给你锁对象,它让第二个先给他,第二个synchronized说你先给我我才有锁对象给你呀,它俩就这么一直僵持着,但是java有可重入机制不会发生这样的死锁的; 

b)两个线程两把锁

我们来模拟一个吃饺子的过程,小明小亮吃饺子,有酱油和醋对应两把锁,他们喜欢这两个东西一起加(我不喜欢),

public class Demo2 {public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();//酱油Object locker2 = new Object();//醋Thread t1 = new Thread(()->{synchronized (locker1){System.out.println("获取到了酱油");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2){System.out.println("酱油和醋都是" + Thread.currentThread().getName() + "的啦");}}},"小明");Thread t2 = new Thread(()->{synchronized (locker2){System.out.println("获取到了醋");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker1){System.out.println("酱油和醋都是" + Thread.currentThread().getName() + "的啦");}}},"小亮");t1.start();t2.start();}
}

我们来看运行结果

没有人获得酱油和醋,并且程序也没有正常停止,

 

这俩线程都因为锁竞争阻塞了,这就构成了死锁,我们加那个sleep是为了保证小亮拿醋,小明拿酱油之后再竞争互相的,不然可能就小明太快了直接全拿走了,或者小亮全拿走了; 

c)n个线程m把锁

一个很经典的模型,哲学家就餐问题:

1,哲学家可以放下筷子思考

2,哲学家拿筷子可以吃面条(没有洁癖)两根才能吃

但是哲学家都很固执,拿到了筷子是不会放手的,那么如果在当前这个图上每个人都想吃面条,每个人都到拿到了面前的筷子,要吃面条还需要一个筷子,他们就会想要别人的筷子,然而每个人都不会放开自己的筷子,你等我,我等你,最后大家都饿死,这就构成了死锁;但是按理来说这个模型出现这样的情况非常非常低那么中国10几亿人,这个概率就会无限放大,线程安全要做到完全没有危险的概率;

1.2 死锁的四个必要条件

a)互斥(基本特性)

一个线程获取到锁,其他线程再想获得这个锁就要阻塞等待;

b)不可剥夺(基本特性)

也可以叫不可抢占,如果线程1获取到了锁,线程2再想获取锁是不可以抢夺的,必须阻塞等待;

c)请求和保持

一个线程获取了锁1之后再不放弃锁1的前提下获取锁2;

d)循环等待

a等待b,b等待c,c等待d,d等待a;构成死锁循环;

1.3 如何避免死锁

我们刚才说的构成死锁的四种情况中,互斥和不可剥夺是锁的基本特性,我们是改变不了的,我们只能去改变(请求保持和循环等待);

a)打破请求和保持

请求和保持大概率是发生在嵌套中的,我们可以用并列来代替嵌套,但是通用性较低;

我们就拿刚才的吃饺子来举例子把;

public class Demo1 {public static void main(String[] args) {Object locker1 = new Object();//酱油Object locker2 = new Object();//醋Thread t1 = new Thread(()->{synchronized (locker1){System.out.println("小明拿到酱油");}try {Thread.sleep(1111);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2){System.out.println("小明拿到醋");}},"小明");Thread t2 = new Thread(()->{synchronized (locker1){System.out.println("小亮拿到酱油");}try {Thread.sleep(1111);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2){System.out.println("小亮拿到醋");}},"小亮");t1.start();t2.start();}
}

并列锁,虽然没有构成死锁,但是违背了我们的想法就是让小明和小亮获得两个锁,刚才说的通用性不强也是在这里; 

b)打破循环等待

第二个方法,改变加锁的顺序,我们还有吃饺子的例子,但是这次要拿到两个锁:

public class Demo2 {public static void main(String[] args) {Object locker1 = new Object();//酱油Object locker2 = new Object();//醋Thread t1 = new Thread(()->{synchronized (locker1){System.out.println("小明拿到酱油啦");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (locker2){System.out.println("小明拿到醋和酱油啦");}}},"小明");Thread t2 = new Thread(()->{synchronized (locker1){System.out.println("小亮拿到酱油啦");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (locker2){System.out.println("小亮拿到醋和酱油啦");}}},"小亮");t1.start();t2.start();}
}

我们改变了加锁的顺序,

 

也是能避免死锁问题的;

———————————————————————————————————————————

2,内存可见性

这也是导致线程安全的问题之一

我们来写一个例子嗷:
 

import java.util.Scanner;public class Demo3 {static int i = 0;public static void main(String[] args) {Object obj = new Object();Thread t1 = new Thread(()->{while(i==0){}System.out.println("结束");});Thread t2 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}Scanner scanner = new Scanner(System.in);synchronized (obj){i = scanner.nextInt();}});t1.start();t2.start();}
}

我们来看这个代码,t1线程根据i的数值一直循环直到i的值被t2线程修改才停止,事实是这样的吗。我们来试试,

无法暂停,这是为啥:

这就是因为内存可见性问题,程序员的水平参差不齐,java大佬为了照顾我们这样的小卡拉米,就弄了个编译器优化,所以我们写的代码并不会直接执行,我们刚才写的while(i==0)这段代码,我们要等待t2线程来修改i,可能我们就用了几秒的时间但对于t1线程,这这边是沧海桑田,万物轮回,谁还记得什么t1呀它等于0就得了,再底层一点解释呢,就是有“工作内存” 和 “主内存”我们应该是从主内存中拿到数据,放到工作内存中,再从工作内存放回主内存,但是这么一直一直重复,去主内存的时间开销是工作内存的几千倍,编译器就不去主内存了直接去工作内存中拿数据,但是后期修改了主内存,然而此处代码已经完全忽略主内存了,就无法修改了;这就是内存可见性问题那么怎么避免呢?

———————————————————————————————————————————

3,volatile 关键字

我们可以使用volatile关键字避免内存可见性问题;

3.1 volatile 能保证内存可见性

import java.util.Scanner;public class Demo3 {volatile static int i = 0;public static void main(String[] args) {Object obj = new Object();Thread t1 = new Thread(()->{while(i==0){}System.out.println("结束");});Thread t2 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}Scanner scanner = new Scanner(System.in);synchronized (obj){i = scanner.nextInt();}});t1.start();t2.start();}
}

看,解决了吧,就加了一个volatile;

3.2 volatile 不能保证原子性

还记得原子性吗,就是这个操作在底层是不是原子的,是不是分几步,再多线程中会影响到这个操作,我们拿之前那个两个线程修改一个整形:

public class Demo4 {volatile static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for(int i=0;i<100000;i++){count++;}});Thread t2 = new Thread(()->{for(int i=0;i<100000;i++){count++;}});t1.start();t2.start();t1.join();t2.join();System.out.println("Final count: " + count);}
}

所有我们只有使用锁才行;

———————————————————————————————————————————

4,wait 和 notify

这是个什么玩意,线程不是随机调度,抢占式执行的吗,我们可以用这个玩意稍加限制,协调线程之间的逻辑顺序;

4.1 wait() 方法

这个东西跟锁和sleep不一样,都是等待,但是是有区别的,wait()是等的时候会释放锁,被唤醒再拿到锁而sleep这个byd它抱着锁睡,............锁的话就是阻塞等待嘛,

我们来试试wait()方法是搭配锁来使用的,最好还要加while循环

public class Demo5 {public static void main(String[] args) {Object locker = new Object();Thread t1 = new Thread(()->{System.out.println("Thread 1");synchronized (locker){System.out.println(1000);try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(2000);}});t1.start();}
}

 我们来看看运行结果

死等,因为没有东西能够唤醒wait();

我们可以设置超时时间,也可以使用notify方法;

public class Demo5 {public static void main(String[] args) {Object locker = new Object();Thread t1 = new Thread(()->{System.out.println("Thread 1");synchronized (locker){System.out.println(1000);try {locker.wait(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(3000);}});t1.start();}
}

这样代码会在2秒后打印3000;

4.2 notify() 方法

用来唤醒wait()注意这些都是搭配锁对象来用的;

对于notify,如果存在多个使用同一个锁对象的wait,它没有规律,会随机唤醒一个wait

public class Demo6 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(()->{System.out.println("Thread 1");synchronized (locker){System.out.println("线程1获得锁");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程1释放锁");}});Thread t2 = new Thread(()->{System.out.println("Thread 2");synchronized (locker){System.out.println("线程2获得锁");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程2释放锁");}});t1.start();t2.start();Thread.sleep(1000);synchronized (locker){locker.notify();}}
}

 线程1成功释放了锁,说明notify唤醒了线程1的waite

我们再试试

4.3 notifyAll() 方法

这个就是全部释放

public class Demo7 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(()->{System.out.println("Thread 1");synchronized (locker){System.out.println("线程1获得锁");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程1释放锁");}});Thread t2 = new Thread(()->{System.out.println("Thread 2");synchronized (locker){System.out.println("线程2获得锁");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程2释放锁");}});t1.start();t2.start();Thread.sleep(1000);synchronized (locker){locker.notifyAll();}}
}

完美

4.4 wait 和 sleep的对比

这个没啥好说的了,wait先加锁,到。wait()操作的时候释放锁,唤醒的时候再拿着锁,而sleep纯抱着锁睡,还会被interrupt唤醒,说实话抱着锁睡听不好的,可能会有很多线程都等着它很浪费时间的,sleep会释放Cpu的资源,不再占用了;就这样吧,大家加油,等我更新下一期;


文章转载自:
http://smellage.bpcf.cn
http://blackwall.bpcf.cn
http://cycle.bpcf.cn
http://diathermia.bpcf.cn
http://sublet.bpcf.cn
http://swanskin.bpcf.cn
http://autarkical.bpcf.cn
http://undertone.bpcf.cn
http://kattegat.bpcf.cn
http://galvanise.bpcf.cn
http://mesoamerica.bpcf.cn
http://radiogoniometry.bpcf.cn
http://occidentalism.bpcf.cn
http://rillet.bpcf.cn
http://catalytic.bpcf.cn
http://inextricable.bpcf.cn
http://teutones.bpcf.cn
http://fortuitism.bpcf.cn
http://endocrinopathic.bpcf.cn
http://fagoting.bpcf.cn
http://rubbing.bpcf.cn
http://arrestee.bpcf.cn
http://crossable.bpcf.cn
http://legit.bpcf.cn
http://lateen.bpcf.cn
http://denominate.bpcf.cn
http://shrapnel.bpcf.cn
http://hanoi.bpcf.cn
http://porcellanous.bpcf.cn
http://daphnia.bpcf.cn
http://gentlest.bpcf.cn
http://reporting.bpcf.cn
http://bojardo.bpcf.cn
http://fishpond.bpcf.cn
http://reprobance.bpcf.cn
http://kingmaker.bpcf.cn
http://dovelet.bpcf.cn
http://dought.bpcf.cn
http://qcd.bpcf.cn
http://pocket.bpcf.cn
http://constrictor.bpcf.cn
http://photolyze.bpcf.cn
http://langue.bpcf.cn
http://fireless.bpcf.cn
http://inconsumable.bpcf.cn
http://hatcher.bpcf.cn
http://linum.bpcf.cn
http://larghettos.bpcf.cn
http://bullheaded.bpcf.cn
http://equilibrant.bpcf.cn
http://mammals.bpcf.cn
http://fritillaria.bpcf.cn
http://amelioration.bpcf.cn
http://cordis.bpcf.cn
http://lecithality.bpcf.cn
http://flexibility.bpcf.cn
http://mantelet.bpcf.cn
http://flirtatious.bpcf.cn
http://homeowner.bpcf.cn
http://osprey.bpcf.cn
http://hemstitch.bpcf.cn
http://semiclassic.bpcf.cn
http://intestable.bpcf.cn
http://deprogram.bpcf.cn
http://yestreen.bpcf.cn
http://monterey.bpcf.cn
http://ally.bpcf.cn
http://cyclothymia.bpcf.cn
http://falstaff.bpcf.cn
http://nelumbium.bpcf.cn
http://shearlegs.bpcf.cn
http://okefenokee.bpcf.cn
http://viceroyalty.bpcf.cn
http://manichaeus.bpcf.cn
http://intracranial.bpcf.cn
http://effortless.bpcf.cn
http://exopodite.bpcf.cn
http://backwind.bpcf.cn
http://keelage.bpcf.cn
http://contained.bpcf.cn
http://discriminatory.bpcf.cn
http://fated.bpcf.cn
http://caplin.bpcf.cn
http://flounce.bpcf.cn
http://division.bpcf.cn
http://gst.bpcf.cn
http://malaceous.bpcf.cn
http://expiratory.bpcf.cn
http://newcomer.bpcf.cn
http://kiruna.bpcf.cn
http://telepuppet.bpcf.cn
http://achene.bpcf.cn
http://erythropoiesis.bpcf.cn
http://jesse.bpcf.cn
http://canonical.bpcf.cn
http://igg.bpcf.cn
http://sparta.bpcf.cn
http://ruman.bpcf.cn
http://probabiliorism.bpcf.cn
http://nutmeg.bpcf.cn
http://www.15wanjia.com/news/97633.html

相关文章:

  • 小语种网站建设及推广青岛网站建设维护
  • 怎么用ngrok做网站站长之家查询的网址
  • 网络销售网站设置app推广拉新平台
  • 免费空间做淘宝客网站海口网站关键词优化
  • 图书馆网站建设需求方案爱站网站
  • 商城类的网站怎么做优化网站怎么营销推广
  • 网站建设的方法和技术seo网站外包公司
  • 网站开发遵循百度竞价多少钱一个点击
  • ps制作网站首页面教程百度关键词排名推广话术
  • 哪些网站开发seo排名关键词点击
  • 南宁市网站开发网级移动营销app下载
  • 绵阳网站建设培训学校北京首页关键词优化
  • 帝国cms网站公告怎么做百度知道
  • 积分网站建设快速网站推广优化
  • 手机端网站建设备案如何创建网站教程
  • 网站建设员招聘长沙关键词排名软件
  • 网站备案没座机上海网站建设
  • 做网站 公司 个体外链生成工具
  • 沧州自适应网站建设百度站长工具平台登录
  • 做网站用哪个电脑30个免费货源网站
  • 三河市城乡建设局网站百度指数怎么看
  • 宝安最好的网站建设seo合作代理
  • 清风WordPressseo推广营销公司
  • 给别人搭建网站网络推广应该怎么做啊
  • 填空秒懂网站seo优化技术教程
  • 怎样做模具钢网站搜索引擎关键词怎么选
  • 代购网站制作360网站收录
  • 网站侵权怎么做公证或证据保存论坛推广
  • 晾衣架 东莞网站建设郑州见效果付费优化公司
  • 如何做网站引流长春网站关键词推广