多线程编程

多线程编程

线程同步

 为什么同步

   -为什么需要同步?

-防止多个线程访问一个数据对象时,对数据造成破坏

-线程的同步保证多线程安全访问竞争资源的一种手段

 同步和锁定

   -关键字:synchronized

   -java中每个对象都有一个内置锁

   -当程序运行到synchronized同步方法或代码块时,自动获得锁

   -一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁。

 对于同步,一般在Java中需要两步:

  -将竞争访问的资源标识为peivate

  -使用synchronized关键字同步方法或代码块。当synchronized方法执行完或出现异常时,会自动释放锁。

eg: 模拟某银行卡账号上有500元。一人拿着存折去取钱,同时另一人拿银行卡去ATM取钱,各取钱500元。

public class ThreadDemo3 {
public static void main(String[] args) {
Bank bank = new Bank();
BankThread b1 = new BankThread(bank);//模拟窗口取钱
BankThread b2 = new BankThread(bank);//模拟ATM取钱
b1.start();
b2.start();
}
}
class BankThread extends Thread{
private Bank bank = null;
public BankThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
//取钱
bank.getMoney(400);
}
}
class Bank {
private double money=500;
public Bank(){}
public Bank(double money){
this.money = money;
}
//synchronized 锁 线程同步 
public synchronized void getMoney(double getMoney){
if(getMoney<0){
System.out.println("取款金额不能为负!\n余额:"+money);
}else if(money-getMoney<0){
System.out.println("余额不足,取款失败!\n余额:"+money);
}else if(money<=0){
System.out.println("取款金额超额,取款失败!\n余额:"+money);
}
else{
//模拟取钱时间
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("取款:"+getMoney);
money-=getMoney;
System.out.println("余额:"+money);
}
}
}


同步产生死锁的原因:

 -当一个线程已经锁取了对象1的锁,同时又想获取对象2的锁。而此时,另一个线程获取了对象2的锁,而又想获取对象1的锁。这种互相等待对方释放锁的过程,会导致“死锁”。

eg: 死锁举例 

[为防止死锁,尽量不要在synchronized同步代码块中嵌套synchronized同步代码块]

public class DieThreadDemo {
public static void main(String[] args) {
Example example = new Example();
DieThread1 dt1 = new DieThread1(example);
dt1.start();
DieThread2 dt2 = new DieThread2(example);
dt2.start();
}
}
class DieThread1 extends Thread{
private Example example=null;


public DieThread1(Example example) {
super();
this.example = example;
}
@Override
public void run() {
example.method1();
}
}
class DieThread2 extends Thread{
private Example example=null;


public DieThread2(Example example) {
super();
this.example = example;
}
@Override
public void run() {
example.method2();
}
}
class Example{
private Object obj1 = new Object();
private Object obj2 = new Object();
public void method1(){
synchronized (obj1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("method1");
}
}
}
public void method2(){
synchronized (obj2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj1) {
System.out.println("method2");
}
}
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值