多线程同步中的门道(二)

 

多线程同步中的门道(二)html

前言java

  在涉及到多线程的开发时,线程同步的考虑是不可缺乏的,不然极可能会形成各类超出预料的错误结果。以本身的学习经从来说,对于刚开始接触线程同步的人可能会感受很是简单,在多线程操做可能会形成数据混乱的地方同步一下不就好了嘛,加个synchronized关键字,多简单!但是随着开发的深刻,会渐渐的发现仅仅是一个synchronized关键字也不是那么简单,里面的门道和考虑到的状况仍是很多。本系列就着按部就班的程序和你们探讨一下synchronized关键字使用中的各类情形和会形成的各类意料以外和意料之中的结果,欢迎各位大神轻拍。多线程

转载请注明本文地址:http://www.cnblogs.com/hellojava/p/3635336.html
ide

系列文章:多线程同步中的门道(一)学习

  synchronized涉及到同步方法、同步代码块、同步类、同步对象、静态方法等,本系列来挨个探讨。测试

  注:由于考虑到文章篇幅和为了突出咱们要分析的关键代码,因此下面程序有可能不会是最优写法。this

同步代码块spa

  同步代码块,分为同步对象和同步类两种,下面咱们来挨个介绍。线程

同步对象code

  咱们首先来看看一个同步对象的例子。

  [测试程序4.1]

/** * Test case 4.1. synchronized code block.synchronized object. */
public class Test { public static void main(String[] args) { // The same object.
        final TestCase test1 = new TestCase(); // final TestCase test2 = new TestCase();
        Thread thread1 = new Thread() { @Override public void run() { test1.function(); } }; Thread thread2 = new Thread() { @Override public void run() { test1.function(); } }; thread2.start(); thread1.start(); } } class TestCase { public void function() { // synchronized object.
        synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " executed result: " + i); } } } }

  程序中使用了同步代码块,同步的是对象。把function中的方法所有给包括起来了,这样进入这个方法的线程会被同步。注意上面main测试程序中两个线程调用的都是同一个对象的function方法。

  运行程序,始终会获得以下结果:

Thread-1 executed result: 0 Thread-1 executed result: 1 Thread-1 executed result: 2 Thread-1 executed result: 3 Thread-1 executed result: 4 Thread-0 executed result: 0 Thread-0 executed result: 1 Thread-0 executed result: 2 Thread-0 executed result: 3 Thread-0 executed result: 4

  从运行结果能够看出,两个线程顺序执行。这就意味着对一个对象的同步是成功的,当一个线程进入这个对象的function方法中的同步代码块时,就锁住了这个对象,第二个线程在想进入这个同步代码块时,就要等待第一个线程执行完同步代码块或抛出异常。

  可是先别急,咱们来看看对不一样对象是否还会起做用。

  [测试程序4.2]

/** * Test case 4.2. synchronized code block.synchronized object. */
public class Test { public static void main(String[] args) { // The different objects.
        final TestCase test1 = new TestCase(); final TestCase test2 = new TestCase(); Thread thread1 = new Thread() { @Override public void run() { test1.function(); } }; Thread thread2 = new Thread() { @Override public void run() { test2.function(); } }; thread2.start(); thread1.start(); } } class TestCase { public void function() { // synchronized object.
        synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " executed result: " + i); } } } }

  对4.1的程序稍做修改,演变成了4.2程序。两个程序的区别就是两个线程分别调用了TestCase类的两个不一样的对象的function方法。

  执行程序,某次运行结果以下所示:

Thread-1 executed result: 0 Thread-1 executed result: 1 Thread-1 executed result: 2 Thread-0 executed result: 0 Thread-0 executed result: 1 Thread-0 executed result: 2 Thread-0 executed result: 3 Thread-1 executed result: 3 Thread-0 executed result: 4 Thread-1 executed result: 4

  在同步代码块中,对对象的同步,当两个线程使用不一样的对象时,就不会顺序执行了,而是交叉执行。说明同步不了不一样的对象。

同步小结

  在同步代码块中,对对象同步时

  • 使用同步对象至关于对对象上锁;
  • 当一个线程进入同步的代码块时,对当前对象上锁,别的线程没法进入这个对象的同步代码,可是能够进入别的对象的方法;
  • 这种同步对象的方式没法放在静态方法中。

同步类

  上面同步对象的方式没法对不一样的对象做线程同步,咱们就来同步类看看。

  [测试程序5.1]

/** * Test case 5.1. synchronized code block.synchronized class. */
public class Test { public static void main(String[] args) { // The different objects.
        final TestCase test1 = new TestCase(); final TestCase test2 = new TestCase(); Thread thread1 = new Thread() { @Override public void run() { test1.function(); } }; Thread thread2 = new Thread() { @Override public void run() { test2.function(); } }; thread2.start(); thread1.start(); } } class TestCase { public void function() { // synchronized class.
        synchronized (TestCase.class) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " executed result: " + i); } } } }

  上面的程序,在同步代码块那里,能够看出是对类进行同步。而且两个线程是分别执行两个不一样对象的function方法。

  运行一下,老是输出结果:

Thread-1 executed result: 0 Thread-1 executed result: 1 Thread-1 executed result: 2 Thread-1 executed result: 3 Thread-1 executed result: 4 Thread-0 executed result: 0 Thread-0 executed result: 1 Thread-0 executed result: 2 Thread-0 executed result: 3 Thread-0 executed result: 4

  两个线程顺序执行,能够看出,当同步类的时候,即使是不一样的线程执行了这个类的不一样对象,线程之间也是同步的。至于其余情形,能够本身作测试用例来验证。

同步类小结

  在同步代码块中,同步类是对类上锁。当一个线程进入了同步代码块,就对类上锁,其余线程没法进入这个类的其余对象的同步方法。

相关文章
相关标签/搜索