- 浏览: 149922 次
- 性别:
- 来自: 五指山
文章分类
最新评论
-
dengdonglin888:
qq_30221445 写道你好 请问这种数据能解吗 < ...
Simple XML -
qq_30221445:
你好 请问这种数据能解吗 <request> ...
Simple XML -
画个逗号给明天qu:
画个逗号给明天qu 写道
Android上传文件到服务器 -
画个逗号给明天qu:
...
Android上传文件到服务器 -
alranger:
我在jsp页面加上这一段代码后,问题还是存在。
解决Ext在ie9报错:不支持extjs对象的“createContextualFragment属性或方法”
转自:http://blog.csdn.net/mq612/article/details/1520583
线程同步
多线程的使用为我们的程序提供了众多的方便,同时它也给我们带来了以往没有考虑过的麻烦。当我们使用多线程处理共享资源时意外将会发生:比如我们一起外出就餐,每个人都是一个线程,餐桌上的食物则是共享资源,当我看到红烧鸡腿上桌后立即拿起筷子直奔目标,眼看着就得手的时候,突然~~~鸡腿消失了,一个距离盘子更近的线程正在得意地啃着。
为了避免上述问题的发生,Java为我们提供了“synchronized(同步化)修饰符”来避免资源冲突,你可以将资源类中某个函数或变量声明为synchronized(同步化),每个继承自Object的类都含有一个机锁(Lock),它是余生俱来的,不需要编写任何代码来启用它。当我们调用任何synchronized(同步化)函数时,该对象将被锁定,对象中所有synchronized(同步化)函数便无法被调用,直到第一个函数执行完毕并解除机锁。
synchronized(同步化)修饰符的使用方式:
1、两个方法在data上是同步的。
Object data = new Object();
public void method1(){
synchronized(data){
//...
}
}
public void method2(){
synchronized(data){
//...
}
}
|
2、两个方法是同步的,method1不能同时有两个使用者,method1和method2之间也不能同时被调用。
public synchronized void method1(){
//...
}
public synchronized void method2(){
//...
}
|
3、使用this关键字,效果同上。
public void method1(){
synchronized (this){
//...
}
}
public void method2(){
synchronized (this){
//...
}
}
|
学会了使用方法,下面就来实际应用一下,我们将要模拟一个银行的存储过程,用线程来模拟银行的各个交易大厅,几乎同时派出6个对同一帐号进行的存取业务,假设每笔业务需要1秒钟来处理,我们来测试一下没有进行同步化处理和进行过同步化的处理的过程和结果。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 线程同步
* 我们模拟一个银行存储过程来证明线程同步的必要性以及在Java中进行线程同步的方法
* 重点:synchronized 修饰符
* @author 五斗米
* @blog http://blog.csdn.net/mq612
*/
public class TestMain5 extends JFrame {
private MyAccounts myAccounts = null; // 我的帐号
private JTextField text = null; // 银行存款数额显示
private JTextArea textArea = null; // 交易过程显示
private JButton button = null; // 开始模拟交易的按钮
/**
* 构造一个银行存取款界面
*/
public TestMain5(){
super("线程同步测试");
myAccounts = new MyAccounts();
text = new JTextField(Integer.toString(myAccounts.inquire()), 10); // 我们在银行中的初始存款为100
textArea = new JTextArea();
textArea.setText("交易日志:");
JScrollPane sp = new JScrollPane(textArea);
button = new JButton("开始交易");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
new Bank("钟楼支行", myAccounts, Bank.DEAL_SAVING, 800);
new Bank("高新支行", myAccounts, Bank.DEAL_SAVING, 1300);
new Bank("小寨支行", myAccounts, Bank.DEAL_FETCH, 200);
new Bank("雁塔支行", myAccounts, Bank.DEAL_FETCH, 400);
new Bank("兴庆支行", myAccounts, Bank.DEAL_SAVING, 100);
new Bank("土门支行", myAccounts, Bank.DEAL_FETCH, 700);
}
});
JPanel pane = new JPanel();
pane.add(text);
pane.add(button);
this.getContentPane().add(pane, BorderLayout.NORTH);
this.getContentPane().add(sp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300, 200);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
/**
* 银行交易大厅类
* 一般银行都会有N个交易大厅,这些大厅可以同时处理多笔业务,这正好符合多线程的特点
*/
class Bank extends Thread{
/**
* 静态字段:用于表示储存
*/
public static final int DEAL_SAVING = 0;
/**
* 静态字段:用于表示提取
*/
public static final int DEAL_FETCH = 1;
private int buy = Bank.DEAL_FETCH; // 默认使取款
private int count = 0;
private MyAccounts myAccounts = null; // 我的帐号
/**
* 构造这个银行交易大厅
* @param name 这个交易大厅的名称
* @param myAccounts 我的银行帐号
* @param buy 行为,参考字段:DEAL_SAVING或DEAL_FETCH
* @param count 钱的数量
*/
public Bank(String name, MyAccounts myAccounts, int buy, int count){
super(name);
this.myAccounts = myAccounts;
this.buy = buy;
this.count = count;
this.start();
}
public void run(){
int $count = 0;
if(buy == Bank.DEAL_SAVING){ // 如果是存款业务
$count = myAccounts.saving(count);
}else if(buy == Bank.DEAL_FETCH){ // 如果是取款业务
$count = myAccounts.fetch(count);
}
text.setText(Integer.toString($count));
textArea.append("/n" + this.getName() + " " + (buy == Bank.DEAL_SAVING ? "存款": "取款") + " 金额:" + count + " 结余:" + $count);
}
}
/**
* 我的帐号
* 进行同步测试
*/
class MyAccounts{
private Integer count = 1100;
public MyAccounts(){
}
/**
* 查询我的帐号
*/
public int inquire(){
synchronized (count){
return count;
}
}
/**
* 存款业务
* @param c 存款的数量
* @return 业务办理完成后的数量
*/
public int saving(int c){
synchronized (count){
//return count += c; // 为了能更好的观察,我们将这个简洁的语句注释掉
int $count = inquire(); // 先查询帐户中的存款
$count += c;
try {
Thread.sleep(1000); // 为了更好的观察,使业务在此停顿1秒钟
} catch (InterruptedException ex) {
ex.printStackTrace();
}
count = $count; // 最后将总数储存起来
return inquire(); // 返回最新的存款数
}
}
/**
* 取款业务
* @param c 取款的数量
* @return 业务办理完成后的数量
*/
public int fetch(int c){
synchronized (count){
//return count -= c; // 为了能更好的观察,我们将这个简洁的语句注释掉
int $count = inquire(); // 先查询帐户中的存款
$count -= c;
try {
Thread.sleep(1000); // 为了更好的观察,使业务在此停顿1秒钟
} catch (InterruptedException ex) {
ex.printStackTrace();
}
count = $count; // 最后将总数储存起来
return inquire(); // 返回最新的存款数
}
}
}
public static void main(String [] args){
new TestMain5();
}
}
|
上面的例子让我们清楚的看到了当采用线程同步技术后,每笔业务都需等待前一笔操作完成后才能开始,现在请把MyAccounts类两个方法中的synchronized (count)语句注释掉,再运行一下程序,输出结果错了吧?
发表评论
-
tesseract-ocr识别中文扫描图片
2013-06-26 16:58 1559http://code.google.com/p/tesse ... -
java获取图片每个像素点的RGB
2013-06-26 16:46 2331http://tinyking.blog.51cto.com/ ... -
Java读取图片EXIF信息
2013-06-26 16:44 543http://hhhk.iteye.com/blog/109 ... -
Java之美[从菜鸟到高手演变]之设计模式
2012-12-10 10:12 735http://blog.csdn.net/zhangerqin ... -
GMT时间对应的解析式
2012-06-21 14:59 673ddd MMM dd HH:mm:ss K yyyy &qu ... -
简易excel读取开发包
2012-06-06 23:29 626http://fastexcel.sourceforge.ne ... -
关于java按字节截取带有汉字的字符串的解法
2012-05-09 23:43 815转自:http://lanxia39.iteye.com/bl ... -
JAVA修饰符类型(public,protected,private,friendly)的通易解释
2012-05-07 18:51 674JAVA修饰符类型(public,protected,pr ... -
Simple XML
2011-12-02 16:26 3347之前曾写过一blog : XStream序列化JAVA对象为X ... -
POI
2011-11-30 17:15 627转自:http://zmx.iteye.com/blog/62 ... -
使用poi读写excel文件
2011-11-30 14:31 643http://cangzhitao.com/java/poi- ... -
JAVA集合类
2011-11-28 22:10 671list:arraylist,vector,linkedlis ... -
POI的使用实例说明
2011-11-28 16:56 980转自:http://zmx.iteye.com/blog/62 ... -
java集合类总结
2011-11-28 09:53 657对象的集合 如果程序的对象数量有限,且寿命可知,那么这个程序是 ... -
[JAVA]Excel 文档操作 .
2011-11-25 11:27 768转自:http://blog.csdn.net/s ...
相关推荐
java线程同步java线程同步java线程同步
电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...
Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 ...
java线程同步实例,哲学家思考的代码实现,应该是一个比较好的例子
Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的...
Java线程(二):线程同步synchronized和volatile 详细讲解Java 同步的原理技术资料
Java多线程同步论文.doc
JAVA代码采用线程来实现数据库的主从同步更新
java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料
java线程同步
主要介绍了Java线程之线程同步synchronized和volatile详解,具有一定参考价值,需要的朋友可以了解下。
Java线程:线程的同步 33 一、 同步方法 35 二、 同步块 36 三、 volatile关键字 38 四、 使用synchronized关键字要注意以下四点 39 五、 关于同步和锁定的一些问题 41 Java线程:并发协作-线程的交互 47 Java线程:...
java多线程知识点,源代码案例,代码案例中包括如何创建线程,主线程,线程优先级,线程组,线程同步,死锁,线程间的通信知识点
Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的...
关于线程同步 synchronize,需要牢牢记住的第一点是:线程同步就是线程排队。同步就是排队。线程同步的目的就是避免线程“同步”执行。
操作系统实验 多线程同步与互斥 java编写 可动态创建
Java多线程同步具体实例.doc
java 多线程同步方法的实例 java 多线程同步方法的实例 java 多线程同步方法的实例
摘要: 活动锁 与 死锁 不同,它是在线程实际工作的时候发生的,但这时还没有完成工作。这通常是在两个线程交叉工作的时候发生,所以第一个线程做的工作被另一个线程取消。一个简单的示例就是:每个线程已经拥有了一...