Java多线程设计模式详解学习笔记三——SingleThreadExecution

Java并发编程案例
本文通过一个Java并发编程案例,展示了在线程间共享资源时可能出现的数据不一致问题,并提供了使用synchronized关键字来解决这一问题的方法。
public class Main { public static void main(String[] args) { Gate gate=new Gate(); new UserThread(gate, "Alice", "Alaska").start(); new UserThread(gate, "Bobby", "Brazil").start(); new UserThread(gate, "Chris", "Canada").start(); } }public class Gate { private int count; private String name="Nobody"; private String address="NoWhere"; void pass(String name,String address){ count++; this.name=name; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.address=address; check(); } private void check() { if (name.charAt(0)!=address.charAt(0)) { System.out.println("********BROKEN*********"+toString()); } } @Override public String toString() { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "Count:"+count+" Namre:"+name+" Address:"+address; } }public class UserThread extends Thread{ private Gate gate; private String name; private String address; public UserThread(Gate gate,String name,String address) { this.gate=gate; this.name=name; this.address=address; } @Override public void run() { System.out.println(name+"BEGIN"); while(true){ gate.pass(name, address); } } }

运行结构:

AliceBEGIN BobbyBEGIN ChrisBEGIN ********BROKEN*********Count:4 Namre:Bobby Address:Canada ********BROKEN*********Count:6 Namre:Alice Address:Alaska ********BROKEN*********Count:6 Namre:Alice Address:Alaska ********BROKEN*********Count:9 Namre:Bobby Address:Brazil ********BROKEN*********Count:10 Namre:Alice Address:Brazil ********BROKEN*********Count:11 Namre:Chris Address:Canada ********BROKEN*********Count:13 Namre:Bobby Address:Canada ********BROKEN*********Count:15 Namre:Alice Address:Alaska ********BROKEN*********Count:15 Namre:Alice Address:Alaska ********BROKEN*********Count:18 Namre:Bobby Address:Brazil ********BROKEN*********Count:19 Namre:Alice Address:Brazil ********BROKEN*********Count:20 Namre:Chris Address:Canada ********BROKEN*********Count:22 Namre:Bobby Address:Canada ********BROKEN*********Count:24 Namre:Alice Address:Alaska ********BROKEN*********Count:24 Namre:Alice Address:Alaska ********BROKEN*********Count:27 Namre:Chris Address:Brazil ********BROKEN*********Count:28 Namre:Alice Address:Brazil测试无法证明安全性:如果测试时找到错误,标明写好的程序并不安全。但是就算测试时没有找到错误也不能保证程序一定是安全的。当测试的次数不够,时间点部队,就可能检查不到问题。
在程序中Gate是SharedResource(共享资源),需要进行共享互斥的操作

public class Gate { private int count; private String name="Nobody"; private String address="NoWhere"; synchronized void pass(String name,String address){ count++; this.name=name; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.address=address; check(); } private void check() { if (name.charAt(0)!=address.charAt(0)) { System.out.println("********BROKEN*********"+toString()); } } @Override public synchronized String toString() { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "Count:"+count+" Namre:"+name+" Address:"+address; } } 运行结果:

BobbyBEGIN AliceBEGIN ChrisBEGINcheck()方法也有name和address字段,为什么没有加synchronized:

因为pass方法调用check()方法,而pass方法已经synchronized了,而check方法又是private的,所以不会有其他线程同时调用这个方法。

看到synchronized时就要思考这个synchronized是在保护什么。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值