您的位置:

同步java,同步卫星

本文目录一览:

java中实现同步的方法有哪两种?

Java的同步可以用synchronized关键字来实现。\x0d\x0a \x0d\x0asychronized可以同步代码,需要绑定一个对象,如synchronized(obj){}\x0d\x0a也可以同步一个方法,是对方法进行线程同步。如public void synchronized methodA(){}

浅谈Java多线程的同步问题

多线程的同步依靠的是对象锁机制 synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问

下面以一个简单的实例来进行对比分析 实例要完成的工作非常简单 就是创建 个线程 每个线程都打印从 到 这 个数字 我们希望线程之间不会出现交叉乱序打印 而是顺序地打印

先来看第一段代码 这里我们在run()方法中加入了synchronized关键字 希望能对run方法进行互斥访问 但结果并不如我们希望那样 这是因为这里synchronized锁住的是this对象 即当前运行线程对象本身 代码中创建了 个线程 而每个线程都持有this对象的对象锁 这不能实现线程的同步

代码    package vista;    class MyThread implements java lang Runnable {     private int threadId;

public MyThread(int id) {      this threadId = id;     }

@Override     public synchronized void run() {      for (int i = ; i ; ++i) {       System out println( Thread ID: + this threadId + : + i);      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      for (int i = ; i ; ++i) {       new Thread(new MyThread(i)) start();       Thread sleep( );      }     }    }

从上述代码段可以得知 要想实现线程的同步 则这些线程必须去竞争一个唯一的共享的对象锁

基于这种思想 我们将第一段代码修改如下所示 在创建启动线程之前 先创建一个线程之间竞争使用的Object对象 然后将这个Object对象的引用传递给每一个线程对象的lock成员变量 这样一来 每个线程的lock成员都指向同一个Object对象 我们在run方法中 对lock对象使用synchronzied块进行局部封锁 这样就可以让线程去竞争这个唯一的共享的对象锁 从而实现同步

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;     private Object lock;

public MyThread(int id Object obj) {      this threadId = id;      this lock = obj;     }

@Override     public void run() {      synchronized (lock) {       for (int i = ; i ; ++i) {        System out println( Thread ID: + this threadId + : + i);       }      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      Object obj = new Object();      for (int i = ; i ; ++i) {       new Thread(new MyThread(i obj)) start();       Thread sleep( );      }     }    }

从第二段代码可知 同步的关键是多个线程对象竞争同一个共享资源即可 上面的代码中是通过外部创建共享资源 然后传递到线程中来实现 我们也可以利用类成员变量被所有类的实例所共享这一特性 因此可以将lock用静态成员对象来实现 代码如下所示

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;     private static Object lock = new Object();

public MyThread(int id) {      this threadId = id;     }

@Override     public void run() {      synchronized (lock) {       for (int i = ; i ; ++i) {        System out println( Thread ID: + this threadId + : + i);       }      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      for (int i = ; i ; ++i) {       new Thread(new MyThread(i)) start();       Thread sleep( );      }     }    }

再来看第一段代码 实例方法中加入sychronized关键字封锁的是this对象本身 而在静态方法中加入sychronized关键字封锁的就是类本身 静态方法是所有类实例对象所共享的 因此线程对象在访问此静态方法时是互斥访问的 从而可以实现线程的同步 代码如下所示

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;

public MyThread(int id) {      this threadId = id;     }

@Override     public void run() {      taskHandler(this threadId);     }

private static synchronized void taskHandler(int threadId) {      for (int i = ; i ; ++i) {       System out println( Thread ID: + threadId + : + i);      }     }    }

lishixinzhi/Article/program/Java/gj/201311/27441

java同步是什么意思

一般有两种方法同步方法和同步代码块

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都可以调用它们。

1.把synchronized当作函数修饰符时,示例代码如下:

PublicsynchronizedvoidmethodAAA()

{

//….

}

这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。

上边的示例代码等同于如下代码:

publicvoidmethodAAA()

{

synchronized(this)//(1)

{

//…..

}

}

(1)处的this指的是什么呢?它指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于objectreference。――那个拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱:(

2.同步块,示例代码如下:

publicvoidmethod3(SomeObjectso)

{

synchronized(so)

{

//…..

}

}

这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

classFooimplementsRunnable

{

privatebyte[]lock=newbyte[0];//特殊的instance变量

PublicvoidmethodA()

{

synchronized(lock){//…}

}

//…..

}

注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Objectlock=newObject()则需要7行操作码。

3.将synchronized作用于static函数,示例代码如下:

ClassFoo

{

publicsynchronizedstaticvoidmethodAAA()//同步的static函数

{

//….

}

publicvoidmethodBBB()

{

synchronized(Foo.class)//classliteral(类名称字面常量)

}

}

代码中的methodBBB()方法是把classliteral作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

记得在《EffectiveJava》一书中看到过将Foo.class和P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。

可以推断:如果一个类中定义了一个synchronized的static函数A,也定义了一个synchronized的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁是Obj这个对象,而B的锁是Obj所属的那个Class。