多线程一

异步: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.

猜你喜欢

转载自blog.csdn.net/qq_39981500/article/details/79746967
今日推荐