技术开发 频道

c#与java的多线程技术比较

     线程的同步

    从概念上来看,线程非常易于理解,实际上,由于他们可能交互地对同一数据结构进行操作,因此它们成为了令编程人员头疼的一种东西。以本文开始的ThreadingExample为例,当它运行时,会在控制台上输出多种不同的结果。从 1 2 3 4 5 1 2 3 4 5到 1 1 2 2 3 3 4 4 5 5或 1 2 1 2 3 3 4 5 4 5在内的各种情况都是可能出现的,输出结果可能与操作系统的线程调度方式之间的差别有关。有时,需要确保只有一个线程能够访问一个给定的数据结构,以保证数据结构的稳定,这也是我们需要线程同步机制的原因所在。

    为了保证数据结构的稳定,我们必须通过使用“锁”来调整二个线程的操作顺序。二种语言都通过对引用的对象申请一个“锁”,一旦一段程序获得该“锁”的控制权后,就可以保证只有它获得了这个“锁”,能够对该对象进行操作。同样,利用这种锁,一个线程可以一直处于等待状态,直到有能够唤醒它信号通过变量传来为止。 

    需要对线程进行同步时需要掌握的关健字 

    synchronized
    lock
    C#中的lock命令实际上是为使用System.Threading.Monitor类中的Enter和Exit方法的语法上的准备

    Object.wait()
    Monitor.Wait( object obj )
    C#中没有等待对象的方法,如果要等待一个信号,则需要使用System.Threading.Monitor类,这二个方法都需要在同步的程序段内执行。

    Object.notify()
    Monitor.Pulse( object obj )
    参见上面的Monitor.Wait的注释。

    Object.notify()
    Monitor.PulseAll( object obj )
    参见上面的Monitor.Wait的注释。
    (特别说明,在上面的表中,每个小节的第一行是java中的方法,第二行是C#中的方法,第三行是有关的注释,由于在文本文件中不能组织表格,请编辑多费点心组织表格,原文中有表格的格式。)

    我们可以对上面的例子进行一些适当的修改,通过首先添加一个进行同步的变量,然后对count()方法进行如下的修改,使变量在“锁”中被执行加1操作。

public static Object synchronizeVariable = "locking variable"; public static void count() { synchronized( synchronizeVariable ) { for( int count=1;count<=5;count++ ) { System.out.print( count + " " ); synchronizeVariable.notifyAll(); if( count < 5 ) try { synchronizeVariable.wait(); } catch( InterruptedException error ) { } } } }

    作了上述的改变后,每次只有一个线程(因为一次只能有一个线程获得synchronizeVariable)能够执行for loop循环输出数字1;然后,它会唤醒所有等待synchronizeVariable的线程(尽管现在还没有线程处于等待状态。),并试图获得被锁着的变量,然后等待再次获得锁变量;下一个线程就可以开始执行for loop循环输出数字1,调用notifyAll()唤醒前面的线程,并使它开始试图获得synchronizeVariable变量,使自己处于等待状态,释放synchronizeVariable,允许前面的线程获得它。这个循环将一直进行下去,直到它们都输出完从1到5的数字。

    通过一些简单的语法变化可以将上述的修改在C#中实现:

public static Object synchronizeVariable = "locking variable"; public static void count() { lock( synchronizeVariable ) { for( int count=1;count<=5;count++ ) { System.out.print( count + " " ); Monitor.PulseAll( synchronizeVariable ); if( count < 5 ) Monitor.Wait( synchronizeVariable ); } } }

 

0
相关文章