基于上一篇文章 最简单的线程同步的例子 本文,旨在探究几种常用的同步的方法:本文的同步指对于一点程序一个时间点只有一个程序在执行,必须一个执行完了,另一个才能执行。
1. 对象同步(同一实例)
成员方法同步
public class MyTestThread extends Thread{讯享网public synchronized void run() { System.out.println(Thread.currentThread().getName()+" come in..."); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" left"); }}
讯享网这样的同步对于下面多个线程使用相同实例是有效的,可以保证在一个时间点只有一个在执行:
MyTestThread a = new MyTestThread();//use the same instance讯享网Thread t1 = new Thread(a, "A"); Thread t2 = new Thread(a, "B"); t1.start(); t2.start()
块同步
private Object lock=new Object(); 讯享网public void run() {
//增加了个锁,锁定了对象lock,在同一个类实例中,是线程安全的,但不同的实例还是不安全的。 synchronized(lock){ System.out.println(Thread.currentThread().getName()+" come in..."); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" left"); } }</code></pre>
其实上面锁定一个方法,等同于下面的: 讯享网 public void run() { synchronized(this) { System.out.println(Thread.currentThread().getName()+" come in..."); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" left"); } }</code></pre>
2. 类同步(多个实例) 对于下面这种多个实例,使用1的方法是不能同步的。要想实现同步,我们有下面几种方法。

讯享网 讯享网 MyTestThread a1 = new MyTestThread(); Thread t1 = new Thread(a1, "A"); MyTestThread a2 = new MyTestThread();//use different instance Thread t2 = new Thread(a2, "B"); t1.start(); t2.start();</code></pre>
变量锁:可以增加一个静态变量,对它进行加锁(后面将说明锁定的对象)。
同步代码如下: 讯享网public class MyTestThread extends Thread{ private static Object lock=new Object(); public void run() { synchronized(lock) { System.out.println(Thread.currentThread().getName()+" come in..."); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" left"); } }
}
还可以加锁在类上如下: 讯享网 public void run() { synchronized(MyTestThread.class) { System.out.println(Thread.currentThread().getName()+" come in..."); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" left"); } }</code></pre>
总结: 1. 无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁,所以首先应知道需要加锁的对象 2. 用synchronized 来锁定一个对象的时候,如果这个对象在锁定代码段中被修改了,则这个锁也就消失了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/50488.html