Java多线程同步 – synchronized 用法

来源:互联网 发布:芗里芗亲app软件下载 编辑:程序博客网 时间:2024/06/06 06:46

1.      利用类对象进行同步

 当两个线程访问同一个类对象时,发生竞争。同步加锁的是对象,而不是代码。

package thrds;public class FiveThread {public static void main(String args[]){ThTst obj = new ThTst();Thread t1 = new Thread(obj);  // 两个线程用同一个对象,发生互斥(属于对象互斥)Thread t2 = new Thread(obj);t1.start();t2.start();}}class ThTst extends Thread {public void run() {tst();}synchronized void tst(){System.out.println(Thread.currentThread().getId() + " in");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getId() + " out");}}输出结果:15 in15 out14 in14 out如果将上述 main函数中改为: Thread t1 = new Thread(new ThTst());  // 使用两个对象,不会发生竞争Thread t2 = new Thread(new ThTst());输出结果:17 in15 in15 out17 out


 

2.      使用类定义和 对象 进行同步(类.class)

即使两个线程分别访问不同的对象,也会发生竞争。加锁的是代码段。

因为一个类的类定义只有一个,因此,到加锁的地方,只能有一个线程进去执行。

注意:null不可用来作为同步对象。

 

package thrds;public class SixThread {public static void main(String args[]){Thread t1 = new Thread(new ThTst2());Thread t2 = new Thread(new ThTst2());t1.start();t2.start();}}class ThTst2 extends Thread {private static Integer iObj = 9;public void run() {tst();}synchronized void tst(){synchronized (ThTst2.class) { //这里可用任何类类型,如 String.class, Integer.class  或使用 其他对象如iObj 也是一样的System.out.println(Thread.currentThread().getId() + " in");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getId() + " out");}}}输出结果:14 in14 out16 in16 out


3.      2中使用对象同步,用来同步的对象,可由参数传入。这样,可提供更多的灵活性,程序员可以控制哪几个线程竞争同一个对象。(在设计时可参考)

package thrds;import org.omg.CORBA.INV_OBJREF;public class SevenThread {public static void main(String args[]){ThTst3 tObj1 = new ThTst3();ThTst3 tObj2 = new ThTst3();String lock = new String("lock"); tObj1.setLock(lock);tObj2.setLock(lock);Thread t1 = new Thread(tObj1);Thread t2 = new Thread(tObj2);t1.start();t2.start();}}class ThTst3 extends Thread {private String lock = null;@Overridepublic void run() {tst();}synchronized void tst(){synchronized (lock) { //同步对象由参数传入System.out.println(Thread.currentThread().getId() + " in");try {Thread.sleep(5000);} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}System.out.println(Thread.currentThread().getId() + " out");}}void setLock(String lock){this.lock = lock;}}输出结果:15 in15 out16 in16 out




synchronized关键字,多线程在同步时,需要看用来同步的对象(包括类定义)是不是唯一的。只有对象是唯一的时候,才会发生互斥。


0 0