线程同步问题分析
发布日期:2021-06-30 17:51:03
浏览次数:5
分类:技术文章
本文共 4178 字,大约阅读时间需要 13 分钟。
我们先看一个例子:
1、三个线程同时执行一个对象中的run方法。我的想法是卖100张票,当ticket =< 0的时候,就不再卖票了,也就是ticket不再减少了。但是运行结果非常奇怪。
package com.huai.test;public class ThreadTest1 implements Runnable { private int ticket = 5; public ThreadTest1() { } @Override public void run() { if (ticket > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " selling ticket : " + ticket--); } } public static void main(String[] args) { ThreadTest1 t1 = new ThreadTest1(); Thread th1 = new Thread(t1, "a"); Thread th2 = new Thread(t1, "b"); Thread th3 = new Thread(t1, "c"); Thread th4 = new Thread(t1, "d"); Thread th5 = new Thread(t1, "e"); th1.start(); th2.start(); th3.start(); th4.start(); th5.start(); }}运行的结果(非常奇怪),正确的结果应该是:5,4,3,2,1这样的顺序
a selling ticket : 5d selling ticket : 2c selling ticket : 2e selling ticket : 3b selling ticket : 4之所以有这样的结果,是因为多个线程共享同一个对象。
问题解决:使用同步代码块或者同步方法。
2、同步代码块
我只在定义方法的地方加上了synchronized关键字
package com.huai.test;public class ThreadTest1 implements Runnable { private int ticket = 5; public ThreadTest1() { } @Override public synchronized void run() { if (ticket > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " selling ticket : " + ticket--); } } public static void main(String[] args) { ThreadTest1 t1 = new ThreadTest1(); Thread th1 = new Thread(t1, "a"); Thread th2 = new Thread(t1, "b"); Thread th3 = new Thread(t1, "c"); Thread th4 = new Thread(t1, "d"); Thread th5 = new Thread(t1, "e"); th1.start(); th2.start(); th3.start(); th4.start(); th5.start(); }}结果为:(注意:这里的线程名字的排列顺序是不确定的,谁先抢到cup资源谁就先运行)
a selling ticket : 5e selling ticket : 4d selling ticket : 3c selling ticket : 2b selling ticket : 13、同步块
在run方法里面加上synchronized (this) {}
package com.huai.test;public class ThreadTest1 implements Runnable { private int ticket = 5; public ThreadTest1() { } @Override public void run() { synchronized (this) { if (ticket > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " selling ticket : " + ticket--); } } } public static void main(String[] args) { ThreadTest1 t1 = new ThreadTest1(); Thread th1 = new Thread(t1, "a"); Thread th2 = new Thread(t1, "b"); Thread th3 = new Thread(t1, "c"); Thread th4 = new Thread(t1, "d"); Thread th5 = new Thread(t1, "e"); th1.start(); th2.start(); th3.start(); th4.start(); th5.start(); }}结果
a selling ticket : 5d selling ticket : 4e selling ticket : 3c selling ticket : 2b selling ticket : 1
补充:当一个对象Object 1在不同的线程中执行这个同步方法时,他们(同一个实例里的同步方法们)之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象Object 2却能够任意调用这个被加了synchronized关键字的方法。
我们用实例说话package com.huai.test;public class ThreadTest1 implements Runnable { private int ticket = 5; public ThreadTest1() { } @Override public void run() { synchronized (this) { if (ticket > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " selling ticket : " + ticket--); } } } public static void main(String[] args) { ThreadTest1 t1 = new ThreadTest1(); Thread th1 = new Thread(t1, "a "); Thread th2 = new Thread(t1, "b "); Thread th3 = new Thread(t1, "c "); Thread th4 = new Thread(t1, "d "); Thread th5 = new Thread(t1, "e "); th1.start(); th2.start(); th3.start(); th4.start(); th5.start(); ThreadTest1 t21 = new ThreadTest1(); Thread th21 = new Thread(t21, "a2"); Thread th22 = new Thread(t21, "b2"); Thread th23 = new Thread(t21, "c2"); Thread th24 = new Thread(t21, "d2"); Thread th25 = new Thread(t21, "e2"); th21.start(); th22.start(); th23.start(); th24.start(); th25.start(); }}结果:
从结果可以看出,对象t1 和对象t21 在同步上面是各自不影响的。但是在同一个对象上面是不共享的。
a selling ticket : 5a2 selling ticket : 5d selling ticket : 4d2 selling ticket : 4e2 selling ticket : 3e selling ticket : 3c selling ticket : 2b2 selling ticket : 2c2 selling ticket : 1b selling ticket : 1
转载地址:https://liangyihuai.blog.csdn.net/article/details/48954109 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年04月15日 11时40分16秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【学习笔记】对vanilla的一些个人理解
2019-04-30
【解决错误】The size of tensor a (8) must match the size of tensor b (64) at non-singleton dimension 1
2019-04-30
word文档中实现目录索引中标题加粗,前导符和页码不加粗
2019-04-30
“学硕” VS “专硕”
2019-04-30
【NLP学习笔记】知识图谱阅读笔记及其心得
2019-04-30
【工具使用】新版CSDN-markdown编辑器使用指南
2019-04-30
《知识图谱》阅读笔记(六)
2019-04-30
【NLP学习笔记】中文分词(Word Segmentation,WS)
2019-04-30
【NLP学习笔记】词性标注(Part-of-speech Tagging, POS)
2019-04-30
《知识图谱》阅读笔记(七)
2019-04-30
《知识图谱》阅读笔记(九)
2019-04-30
【超越白皮书7】你需要知道关于ETH2.0的几个事实
2019-04-30
超越白皮书8:穿云而过的闪电网络
2019-04-30
AMM做市无常损失对冲分析系列(一)—— 损益及期权对冲模型构建
2019-04-30
JS中document对象和window对象有什么区别
2019-04-30
【python练习题】遍历1
2019-04-30
【matlab】显示图片且下方显示文字
2019-04-30