异步:t1线程执行t1的,t2线程执行t2的,两个线程之间谁也不等谁
同步编程模型:t1线程和t2线程执行,t1线程必须等待t2线程执行结束后,t1线程才能执行,这是同步编程,模型
什么时候需要同步呢?
1.需要数据安全。线程同步机制使程序变成了(等同)单线程
2.什么条件下使用同步?
(1).必须是多线程环境
(2).多线程环境共享同一个数据
(3).共享的数据及到修改操作
public class Account {
private String actno;
private double balance;
public Account(String actno, double balance) {
super();
this.actno = actno;
this.balance = balance;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String drawMoney(double money) {
// 括号里面的是共享对象 就是这个账户
// 让synchronized括号里面的代码永远只有一个线程执行
synchronized (this) {
if (this.balance - money < 0) {
return "余额不足";
} else {
this.balance -= money;
return "取款 " + money + " 成功";
}
}
}
public void saveMoney(double money) {
this.balance += money;
}
}
public class Porcessor implements Runnable{
Account account;
public Porcessor(Account account) {
this.account = account;
}
@Override
public void run() {
System.out.println(account.drawMoney(3000.0));
}
}
public class Test {
public static void main(String[] args) {
Account act = new Account("cc-001", 5000);
Porcessor p = new Porcessor(act);
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
t1.start();
t2.start();
}
}
//结果
//取款 3000.0 成功
//余额不足
原理: t1线程执行到此处,遇到了synchronized关键字,就会去找this的对象锁如果找到this 对象锁,则进入同步语句块中执行程序。当同步语句块中的代码执行结束之后,t1线程归还this的对象锁
在t1线程执行同步语句块的过程中,如果t2线程也过来执行以下代码,也遇到synchronized关键字, 所以也去找this的 对象锁,但是该对象t1线程持有,只能在这等待this对象的归还。
public class RunnableDemo implements Runnable{
MyClass mc;
public RunnableDemo(MyClass mc) {
this.mc = mc;
}
@Override
public void run() {
try{
if(Thread.currentThread().getName().equals("t1")) mc.method1();
if(Thread.currentThread().getName().equals("t2")) mc.method2();
}catch (Exception e) {
System.out.println("Thread "+ (Thread.currentThread().getName()) + " interrupted.");
}
System.out.println("Thread " + (Thread.currentThread().getName()) + " exiting.");
}
}
public class MyClass {
//因为是共享对象,t1线程拿走了对象锁
public synchronized void method1(){
System.out.println("method1....");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//t2线程想要执行,但是对象锁被t1拿走了,所以只有等待t1线程执行完毕才能执行
public synchronized void method2(){
System.out.println("method2....");
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
RunnableDemo rd = new RunnableDemo(new MyClass());
Thread t1 = new Thread(rd);
Thread t2 = new Thread(rd);
t1.setName("t1");
t2.setName("t2");
t1.start();
Thread.sleep(1000);
t2.start();
}
}
//结果
//method1....
//method2....
//Thread t1 exiting.
//Thread t2 exiting.