Java中的多线程编程(二)

来源:互联网 发布:网络实名制的利弊 编辑:程序博客网 时间:2024/06/17 17:51

线程同步处理

    多线程编程的目的是提高资源利用率和缩短系统的响应时间,它的特征是多个线程并发执行。有时候在进行多线程的程序设计中需要实现多个线程共享同一段代码,从而实现共享同一个私有成员或类的静态成员的目的。这时,由于线程与线程之间相互竞争CPU资源,使得线程无序的访问这些共享资源,可能导致结果不正确。

一、同步代码块

   Java虚拟机为每个对象配备一把锁和一个等候集,这个对象可以是实例对象,也可以是类对象。
   一个类的静态成员方法变量和静态成员方法属于类对象,而一个类的非静态成员变量和非静态成员方法属于类的实例对象。
  • 对实例对象进行加锁,能够保证与这个实例对象相关联的线程可以互斥的使用对象的锁;
  • 对类对象进行加锁,能够保证与这个类相关联的线程可以互斥的使用类对象的锁。  
  通过new关键字创建实例对象,从而获得对象的引用, 要获得类对象的引用,我们可通过java.lang.Class类的forName成员方法,forName的声明格式如下:
 public static Class forName(String classname) throws ClassNotFoundException
    注释:Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构java通常是先有类再有对象,有对象我就可以调用方法或者属性。反射其实是通过Class对象来调用类里面的方法。通过反射可以调用私有方法和私有属性。大部分框架都是运用反射原理。
    java在编译和运行时,会将需要被编译和运行的所有类加载进类加载器,每个类被加载之后,系统就会为该类生成一个对应的Class对象,通过该Class对象就可以访问到java虚拟机中的这个类,进而在运行时对这个被访问的类进行信息的获取和处理(当然,不管被访问的这个类里的信息是否私有的);通俗的讲,Class对象间接代表了它对应的类,通过这个Class对象,我们就可以大刀阔斧地去执行反射机制的实现;
通过java反射获得加载类,获得类的实例,       还有可以获得类中的私有成员属性。     Class c=Class.forName("类的名称");//通过配置文件     c.newInstance();//得到类的无参构造     c.getDeclaredFields();//获得本类的所有成员     c.getFields();//获得本类以及父类的一些公有属性 在一个方法中(类的方法中),用synchronized声明的语句块成为同步代码块,同步代码块的语法如下:
     synchronized(synObject)
     {
       //关键代码;
     }
 synchronized块是这样一个代码块,其中的代码必须获得对象synObject的锁才能执行。当一个线程欲进入该对象的关键代码时,JVM将检查该对象的锁是否被其它的线程获得,如果没有,则JVM把该对象的锁交给当前请求的锁的线程,该线程获得锁后就可以进入关键代码区域。

二、同步方法

  同步方法和同步代码块的功能一样,都是利用互斥锁实现关键代码的同步访问。只不过同步方法的关键代码就是一个方法的方法体,此时只需要调用synchronized关键字修饰该方法即可。一旦被synchronized关键字修饰的方法已被一个线程调用,那么所有其他试图调用同一实例中的方法的线程都必须等待,直到该方法被调用结束后释放其它锁给下一个等待的线程。
  通过在方法声明中加入synchronized关键字来声明synchronized方法。
 public synchronized void accessVal(int newVal);
 这种机制确保同一时刻对于每一个对象,其所有声明为synchronized的成员方法中最多只有一个处于可执行状态,因为最多只有一个能够获得该类实例对应的锁,从而避免了类成员变量的访问冲突。
 在Java中,不光是类实例,每一个类也对应一把锁,这样我们也可以将类的静态成员函数声明为:synchronized,以控制其对类的静态成员变量的访问。

synchronized块 :直接锁定指定的对象,,,,该对象在多个地方的同步锁定块,,,只能多线程同时执行其中一个其他未获得锁的线程需要等待获得锁的线程执行完成并释放锁,如果同时有多个线程等待锁释放,,那么锁释放后,等待的线程谁会获得锁,,这个不同JVM可能有差异。

synchronized 修饰非静态方法 : 锁定的是该类的实例  同一实例在多线程中调用才会触发同步锁定  所以  多个被synchronized修饰的非静态方法在同一实例下  只能多线程同时调用一

synchronized 修饰静态方法:锁定的是类本身,而不是实例,  同一个类中的所有被synchronized修饰的静态方法, 只能多线程同时调用一个

1 0