张孝祥[致敬]-多线程学习第03课-线程的互斥与同步
2016-11-08 22:03
225 查看
本文地址:http://blog.csdn.net/hblfyla/article/details/53089014
1.线程的互斥
为什么会有线程的互斥?可以想银行取款的问题,如果不做监控,多个人同时针对一个存折取钱的时候就会出现钱不对的问题,下面我们通过两个例子来分析一下线程的互斥问题以及为什么会产生这个线程?
例子1:一个人生产信息,一个人消费信息
面向对象的思想:类 信息类 生产者 消费者代码:
package org.yla.lxh.day03; /** * 传统线程互斥问题 * * @author yangluan 2016年11月8日下午9:05:13 */ public class TriditionalThreadSafeLxh { public static void main(String[] args) { // 多个线程调用同一个对象,会带来数据错乱线程,产生的原因分析: // 多个线程调用一个对象的某个方法 Info info = new Info(); Production p = new Production(info); Consumer c = new Consumer(info); new Thread(p).start(); new Thread(c).start(); } } class Info { private String name = "李兴华"; private String content = "讲师"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } class Production implements Runnable { private Info info; public Production(Info info) { this.info = info; } @Override public void run() { for (int i = 0; i < 20; i++) { if (i % 2 == 0) { this.info.setName("李兴华"); try { Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("讲师"); }else{ this.info.setName("mldn"); try { Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("www.mldn.cn"); } } } } class Consumer implements Runnable{ private Info info; public Consumer(Info info) { this.info = info; } @Override public void run() { for (int i = 0; i < 20; i++) { try { Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.info.getName()+","+this.info.getContent()); } } }运行:
mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 李兴华,www.mldn.cn mldn,讲师 mldn,www.mldn.cn
面向对象:打印输出类
代码:
package org.yla.zxx.day03; /** * 传统线程互斥问题例子2 * 多个线程同时打印不同人名字 * @author yangluan * 2016年11月8日下午9:28:09 */ public class TraditionalThreadSafe { public static void main(String[] args) { new TraditionalThreadSafe().init(); } public void init(){ final OutputMessage c = new OutputMessage(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(120); } catch (InterruptedException e) { e.printStackTrace(); } c.output("aaaaa"); } }).start(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(120); } catch (InterruptedException e) { e.printStackTrace(); } c.output("bbbbb"); } }).start(); } class OutputMessage{ public void output(String name){ while(true){ for (int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i));//打印一个人的名字 } System.out.println(); } } } }
运行;
bbbbb bbbbb aaaa aabbbbb bbbbb bbbbb
通过上面两个例子我们分析得出线程互斥问题产生的原因:
(1)多个线程调用同一个对象的某个方法
(2)在线程的run()方法中使用sleep更好的显示出数据错乱线程
怎么解决上面的问题?
既然产生的原因是在调用这个对象的方法时候造成互斥,那么我就在这个方法或者代码块实现同步
下面用例子2看一下解决的办法:
代码:
package org.yla.zxx.day04; /** * 传统线程互斥问题例子2 * 多个线程同时打印不同人名字 * @author yangluan * 2016年11月8日下午9:28:09 */ public class TraditionalThreadSafe { public static void main(String[] args) { new TraditionalThreadSafe().init(); } public void init(){ final OutputMessage c = new OutputMessage(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(120); } catch (InterruptedException e) { e.printStackTrace(); } c.output("aaaaa"); } }).start(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(120); } catch (InterruptedException e) { e.printStackTrace(); } c.output("bbbbb"); } }).start(); } class OutputMessage{ public synchronized void output(String name){ // synchronized (this) { while(true){ for (int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i));//打印一个人的名字 } System.out.println(); } // } } } }
运行:
bbbbb bbbbb bbbbb bbbbb bbbbb
(1)同步代码块调用的是当前对象
(2)在方法上使用同步调用的当前对象
(3)在静态static方法上使用同步调用的类.class,因为静态方法是类直接调用,锁就是这个类的字节码
本文地址:http://blog.csdn.net/hblfyla/article/details/53089014
相关文章推荐
- 张孝祥[致敬]-多线程学习第01课 传统线程的创建
- 张孝祥[致敬]-多线程学习第04课-线程的通信机制
- 张孝祥[致敬]-多线程学习第06课-多个线程之间的共享变量
- 张孝祥[致敬]-多线程学习第05课-线程范围内的共享变量
- .NET组件程序设计 第8章 多线程和并发管理 同步线程_互斥
- 介绍Linux下面线程的操作、多线程的同步和互斥
- java多线程详解(3)-线程的互斥与同步
- 多线程学习(八)线程的同步-同步块
- 介绍Linux下面线程的操作、多线程的同步和互斥
- java基础——多线程(线程的同步互斥与通信)
- JAVA基础学习(十一)--多线程一线程的创建,运行,同步和锁
- Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解
- 马士兵-多线程学习第04课 线程的同步
- Linux多线程编程(不限Linux)——本文一个例子展开,介绍Linux下面线程的操作、多线程的同步和互斥。
- 基础学习day11--多线程一线程的创建,运行,同步和锁
- .net多线程学习笔记 3 线程间同步
- 秒杀多线程系列之⑤ 经典线程之同步 关键段实现互斥
- 讲Linux下面线程的操作、多线程的同步和互斥相关函数及操作的文章链接
- java基础——多线程(线程的同步互斥与通信)
- java多线程学习-同步之线程通信