• Java多线程-线程的锁总结


    一、多线程-同步函数的锁是this



    /*
    同步函数用的是哪一个锁呢?
    函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
    所以同步函数使用的锁是this。

    通过该程序进行验证。

    使用两个线程来买票。
    一个线程在同步代码块中。    这两个的锁不一样
    一个线程在同步函数中。
    都在执行买票动作。


    */


    class Ticket implements Runnable
    {
        private  int tick = 100;
        Object obj = new Object();
        boolean flag = true;
        public  void run()
        {
            if(flag)
            {
                while(true)
                {
                    synchronized(this)    /*同步函数的锁*/
                    {
                        if(tick>0)
                        {
                            try{Thread.sleep(10);}catch(Exception e){}
                            System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                        }
                    }
                }
            }
            else
                while(true)
                    show();           /*使用this锁*/
        }
        public synchronized void show()//this
        {
            if(tick>0)
            {
                try{Thread.sleep(10);}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
            }
        }
    }


    class  ThisLockDemo
    {
        public static void main(String[] args)
        {

            Ticket t = new Ticket();

            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
            t1.start();
            try{Thread.sleep(10);}catch(Exception e){}
            t.flag = false;
            t2.start();


    //        Thread t3 = new Thread(t);
    //        Thread t4 = new Thread(t);
    //        t3.start();
    //        t4.start();


        }
    }

    二、多线程-静态同步函数的锁是class对象


    /*
    如果同步函数被静态修饰后,使用的锁是什么呢?

    通过验证,发现不在是this。因为静态方法中也不可以定义this。

    静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
    类名.class  该对象的类型是Class


    静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
    */
    class Ticket implements Runnable
    {
        private static  int tick = 100;
        //Object obj = new Object();
        boolean flag = true;
        public  void run()
        {
            if(flag)
            {
                while(true)
                {
                    synchronized(Ticket.class)           /*使用了静态,锁就变了*/
                    {
                        if(tick>0)
                        {
                            try{Thread.sleep(10);}catch(Exception e){}
                            System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                        }
                    }
                }
            }
            else
                while(true)
                    show();
        }
        public static synchronized void show()
        {
            if(tick>0)
            {
                try{Thread.sleep(10);}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
            }
        }
    }


    class  StaticMethodDemo
    {
        public static void main(String[] args)
        {

            Ticket t = new Ticket();

            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
            t1.start();
            try{Thread.sleep(10);}catch(Exception e){}
            t.flag = false;
            t2.start();


        }
    }

    三、多线程-单例设计模式-懒汉式 出现的安全问题


    /*
    单例设计模式。 必须要记住,面试题
    饿汉式与懒汉式的区别
    1.懒汉式是延时加载的形式
    2.懒汉式由于是延时加载,所以在多线程中会出现安全问题
    3.可以加同步函数或者同步代码块来解决,而同步函数每次都需要判断比较慢
    4.这里采用同步代码块来解决安全问题
    5.由于函数是静态的,所以锁是类名.class

    */
    //饿汉式。
    /*
    class Single
    {
        private static final Single s = new Single();
        private Single(){}
        public static Single getInstance()
        {
            return s;
        }
    }
    */


    //懒汉式           

    class Single
    {
        private static Single s = null;
        private Single(){}


        public static  Single getInstance()
        {
            if(s==null)
            {
                synchronized(Single.class)
                {
                    if(s==null)
                        //--->A;
                        s = new Single();
                }
            }
            return s;
        }
    }

    class SingleDemo
    {
        public static void main(String[] args)
        {
            System.out.println("Hello World!");
        }
    }

    四、死锁(要避免出现和熟悉)



    class Test implements Runnable
    {
        private boolean flag;
        Test(boolean flag)
        {
            this.flag = flag;
        }

        public void run()
        {
            if(flag)
            {
                while(true)
                {
                    synchronized(MyLock.locka)
                    {
                        System.out.println(Thread.currentThread().getName()+"...if locka ");
                        synchronized(MyLock.lockb)
                        {
                            System.out.println(Thread.currentThread().getName()+"..if lockb");                    
                        }
                    }
                }
            }
            else
            {
                while(true)
                {
                    synchronized(MyLock.lockb)
                    {
                        System.out.println(Thread.currentThread().getName()+"..else lockb");
                        synchronized(MyLock.locka)
                        {
                            System.out.println(Thread.currentThread().getName()+".....else locka");
                        }
                    }
                }
            }
        }
    }


    class MyLock
    {
        static Object locka = new Object();     /*静态,能用类名直接调用*/
        static Object lockb = new Object();
    }

    class  DeadLockTest
    {
        public static void main(String[] args)
        {
            Thread t1 = new Thread(new Test(true));
            Thread t2 = new Thread(new Test(false));
            t1.start();
            t2.start();
        }
    }

  • 相关阅读:
    physicsbased animation阅读计划
    读代码的一点感想
    Paired Joint Coordinates
    坐标变换
    ADO.NET用法示例
    希腊字母读法
    数据库系统概论(第三版)学习笔记
    在网页里让文本框只能输入数字的一种方法。外加回车换Tab (javascript key键的使用)+禁止切换输入法转
    常用的一些javascript小技巧
    在.NET2.0中上传文件操作(解决了上传文件大小和多文件限制)转
  • 原文地址:https://www.cnblogs.com/liangqiyuan/p/5660317.html
Copyright © 2020-2023  润新知