多线程入门-第七章-线程的同步Synchronized

/*
    异步编程模型:两个线程执行自己的,互不影响。

    同步编程模型:t1和t2执行,t2必须等t1执行结束之后才能执行。

    为什么要线程同步?
        1、为了数据的安全,尽管应用程序的使用率降低,但是为了保证数据是安全的,必须加入线程同步机制。线程同步机制使程序变成了(等同于)单线程。

        2、什么条件下使用线程同步?
            一、必须是多线程环境
            二、多线程环境共享同一个数据
            三、共享的数据涉及到修改操作。
*/
public class ThreadTest06 
{
    public static void main(String[] a) 
    {
        //创建一个公共的账户
        Account act = new Account("no-001",5000.0);

        Processor p = new Processor(act);
        
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(p);

        t1.start();

        t2.start();

    }

    static class Processor implements Runnable
    {
        Account act;

        //构造方法,为了共享同一个对象
        public Processor(Account act){
            this.act = act;
        }
        public void run(){
            act.withdraw(1000);
            System.out.println("取款成功,余额:"+act.getBalance());
        }
    }

    static class Account
    {
        private String no;
        private double balance;

        public Account(){}

        public Account(String no,double balance){
            this.no = no;
            this.balance = balance;
        }

        public void setNo(String no){
            this.no = no;
        }

        public void setBalance(double balance){
            this.balance = balance;
        }

        public String getNo(){
            return no;
        }

        public double getBalance(){
            return balance;
        }

        //取款
        public void withdraw(double money){
        
            //吧把需要同步的代码,放到同步语句块中。
            /*
                原理:t1和t2线程,t1线程执行到此处,遇到了synchronized关键字,就会去找this的对象锁,
                如果找到this对象锁,则进入同步语句块中执行程序。当同步语句块中的代码执行结束后,t1线程
                归还this的对象锁。

                在t1执行同步语句块的过程中,如果t2线程也过来执行以下代码,也遇到关键字synchronized,所以也去找
                this的对象锁,但是该对象锁被t1持有,只能在这等待this对象的归还。
            
            */
            synchronized(this){
                double after= balance - money;

                try{
                    Thread.sleep(1000);    
                }catch(Exception e){
                
                }
                this.setBalance(after);
            }
        }
    }
}
/*
    类锁
*/
public class ThreadTest06 
{
    public static void main(String[] a) throws Exception
    {
        Thread t1 = new Thread(new Processor());
        Thread t2 = new Thread(new Processor());

        t1.setName("t1");
        t2.setName("t2");

        t1.start();
        //为了保证t1先执行
        Thread.sleep(1000);
        t2.start();

    }

   static class Processor implements Runnable
    {
        public void run(){
            if("t1".equals(Thread.currentThread().getName())){
                MyClass.m1();
            }
            if("t2".equals(Thread.currentThread().getName())){
                MyClass.m2();
            }
        }
    }
    
    static class MyClass
    {
        //synchronized添加到静态方法上,线程执行此方法的时候会找类锁
        public synchronized static void m1(){
            try{
                Thread.sleep(10000);
            }catch(Exception e){
            }
            System.out.println("m1......");
        }

        //不会等m1结束,因为该方法没有被synchronized修饰
        /*public static void m2(){
            System.out.println("m2......");
        }
        */

        //m2会等m1结束之后才会执行,因为类锁只有一个
        public synchronized static void m2(){
            System.out.println("m2......");
        }
    }
}
/*
    死锁
*/
public class DeadLock 
{
    public static void main(String[] args) 
    {
        Object o1 = new Object();
        Object o2 = new Object();

        Thread t1 = new Thread(new T1(o1,o2));

        Thread t2 = new Thread(new T2(o1,o2));

        t1.start();
        t2.start();
    }
}

class T1 implements Runnable
{
    Object o1;
    Object o2;

    T1(Object o1,Object o2){
        this.o1 = o1;
        this.o2 = o2;
    }
    public void run(){
        synchronized(o1){
            try{Thread.sleep(1000);}catch(Exception e){}
            synchronized(o2){
            
            }
        }
    }
}

class T2 implements Runnable
{
    Object o1;
    Object o2;

    T2(Object o1,Object o2){
        this.o1 = o1;
        this.o2 = o2;
    }
    public void run(){
        synchronized(o2){
            try{Thread.sleep(1000);}catch(Exception e){}
            synchronized(o1){
            
            }
        }
    }
}

 

posted @ 2017-05-02 16:35  bookwed  阅读(203)  评论(0)    收藏  举报