zoukankan      html  css  js  c++  java
  • java多线程知识汇总(三)如何选择锁?如何加锁

    1.锁,保证的是被锁的代码,一次执行完毕才能被其他线程执行,锁保证了一个线程执行过程中不被其他线程打断。以保证数据的准确性。

    2。数据的读写过程,是有冲突的,当一个线程正在读数据,另一个线程正在写同一个数据,就有可能导致数据不准确,造成脏数据。就要保证读写分开时间段。即加锁。

    3.如果想要保证共享对象的一个方法按序执行,则在这个方法上加锁。

    4.多个方法加同一个锁:在多个方法上加同一个锁。如果想保证读写能读取到准确数据,则在同一成员变量的对应读写方法上加同一个锁,同一个锁。保证读写正常。

    5.同一个类中加不同的锁,比如一个加的this锁,一个加的object的锁,则此两个方法不受任何影响,多线程可以分别同时运行这两种各方法。

    但是如果一个类的躲个方法加同一个锁,则只能按序访问。

    下面举例说明,同一个类加不同的锁,一个this锁,一个同步代码块的object的锁。

    单例对象包括不同的锁:

    public class Student {
        private String age = "12";
        private String name = "Tome";    
        private static Student student = new Student();
        private Object object = new Object();
        
        public void setName(String string) {
            synchronized (object) {
                System.out.println("i am running");
            }    
        }
        synchronized public String getNameAndAge() {
            return name+":"+age;
        }
        synchronized public void setNameAndAge(String name,String age) {
            this.name = name;
            this.age = age;
        }
    
        private Student()
        {        
        }
        public static Student GetInstace() {
                return student;
        }
    }

    线程1负责占用单例对象的this锁,且sleep让它一直占用

    public class MyThread extends Thread {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            Student.GetInstace().setNameAndAge("111", "111");//占用this锁的方法
            try {
                System.out.println("i am sleeping");//打印输出我在休眠,一直占用this锁
                Thread.currentThread().sleep(500);//睡眠,一直占用this锁,因为调用的是this锁的方法
                System.out.println("i wake up");//打印输出我占用完毕
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    线程2负责执行object同步块代码,同步块调用的是另一个锁,即object锁。

    public class AppMain implements Runnable{
    
        public static void main(String[] args) {
            AppMain appMain = new AppMain();
            MyThread thread2 = new MyThread();
            thread2.start();
            for(int i =0;i<200;i++)
            {
            Thread thread1 = new Thread(appMain);
            thread1.start();    
            }
        }    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            Student.GetInstace().setName("3333");//调用的是object锁的方法
        }

    打印继续向下看

    结论:同一个类的不同锁,多线程在执行锁住的代码时,多线程不互联影响。

  • 相关阅读:
    java中Switch的实现原理浅谈
    漫谈计算机编码:从ASCII码到UTF8
    从斐波那契数列看java方法的调用过程
    Java中的位运算及简单的算法应用介绍
    在powserdesigner中,如何将Name(中文注释)导入到sqlserver的字段说明中?
    关于ArcMap的符号库和字体
    ORACLE CHAR,VARCHAR,VARCHAR2,NVARCHAR类型的区别与使用
    在window 2008 上安装arcgisserver93,报arcgissom 密码不符合安全策略
    Power Designer反向数据库时遇到sqlstate=37000错误,解决方案!
    解决PowerDesigner 反向工程没有注释且如何将注释转换成PDM的name
  • 原文地址:https://www.cnblogs.com/panxuejun/p/5920641.html
Copyright © 2011-2022 走看看