java 从零开始,学习笔记之基础入门<线程及实例分析>(十九)(六)

2014-11-24 08:29:18 · 作者: · 浏览: 5
就应该对发生的这种情况进行控制,控制在调用
//取钱方法时,只能有一个线程调用,如果调用的这个线程没有结束,那么其他的线程都不能够
//访问这个方法.
public static void main(String[] args) {
//创建账户
CwAcount ca = new CwAcount("mm", 1200);
WmDemo wm = new WmDemo(ca, 1000);
wm.setName("网名存折");
wm.start();
WmDemo wm1 = new WmDemo(ca, 1000);
wm1.setName("网名卡");
wm1.start();
}
}
package com.ibm.sync;
public class CwAcount {
private String acountno;
private double acountmoney;
public CwAcount(String acountno,double acountmoney){
this.acountno=acountno;
this.acountmoney=acountmoney;
}
//提供一个取钱的方法
//money表示你需要取的钱数
public void getMoney(double money)throws InterruptedException{
//取钱之前需要对账户的信息进行验证
if(acountmoney>=money){
Thread.sleep(1000);
acountmoney=acountmoney-money;
System.out.println(Thread.currentThread().getName()+"取钱成功,账户余额为:"+acountmoney);
}else{
System.out.println("不好意思多赚点钱了再来!");
}
}
}
package com.ibm.sync;
public class WmDemoextends Thread{
CwAcount ca;
double money;
public WmDemo(CwAcount ca ,double money){
this.ca = ca ;
this.money = money;
}
public void run(){
//对这个对象进行枷锁,表明只能有一个线程来访问这个对象
//当当前线程对这个对象操作结束后,那么其他线程才能够操作这个对象
synchronized (ca) {
try {
ca.getMoney(money);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
多线程
编程知识概括
使用synchronized关键字修饰一个对象时,表明此对象在任意时刻只能有一个线程来操作此对象,在操作对象时,其他线程处于等待状态,只有等待操作的线程执行完毕之后,那么其他的线程才能够操作此对象。
释放对象锁的条件:
当线程执行到synchronized()块结束时,释放对象锁。
当在synchronized()块中遇到break,return或抛出exception,则自动释放对象锁。
当一个线程调用wait()方法时,它放弃拥有的对象锁并进入等待队列(按照优先级来说,等待线程高于给对象加锁)
死锁:
就是两个线程之间相互等待,都等待对象释放资源供自己使用,了但是在同一时刻,两个线程都不释放资源,那么两个线程就一直处于等待状态,那么线程的死锁就出现了。线程的死锁是可以采取操作避免出现的。
1. Wait(), notify() notifyall()都是出自于Object类
2. 调用wait()方法使线程处于等待状态,要想改变线程的等待状态,可以调用线程类的中断方法或者是调用object()类的notify()或者notifyAll方法
3. notify是用来唤醒单个线程的等待状态 notifyAll是用来唤醒多个线程等待状态
同步方法:指的是线程中调用方法时同步,具体的指明多个线程同时调用一个相同的方法,一般情况下,这样会造成同时执行操作会降低处理效率。
避免无谓的同步方法
因为同步会降低程序的执行效率,所以应该避免无谓的同步
通过所谓的Fine-Grained锁的机制,可以避免这种情况
多线程编程一般规则:
如果两个或两个以上的线程都修改一个对象,那么把执行修改的方法定义为被同步的,如果对象更新影响到只读方法,那么只读方法也要定义成同步的。
不要滥用同步。如果在一个对象内的不同的方法访问的不是同一个数据,就不要将方法设置为synchronized的。
如果一个线程必须等待一个对象状态发生变化,那么他应该在对象内部等待,而不是在外部。他可以通过调用一个被同步的方法,并让这个方法调用wait()。
每当一个方法返回某个对象的锁时,它应当调用notifyAll()来让等待队列中的其他线程有机会执行。
记住wait()和notify()/notifyAll()是Object类方法,而不是Thread类的方法。仔细查看每次调用wait()方法(等待方法),都有相应的notify()/notifyAll()方法(唤醒方法),且它们均作用于同一个对象。
多线程编程一般规则(con.)
a) 针对wait()、notify()/notifyAll()使用旋锁(spin lock);
b) 优先使用notifyAll()而不是notify();
c) 按照固定的顺序获得多个对象锁,以避免死锁;避免同时对对象进行加锁
d) 不要对上锁的对象改变它的引用;
e) 不要滥用同步机制,避免无谓的同步控制。