for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread.getName + " " + i);}
System.out.println("Completed printing Numbers for " + Thread.currentThread.getName);}
代码中只是给方法添加了一个synchronized关键字,没有其它的改动。现在我们运行上面的代码,得到如下所示的结果:
Starting to print Numbers for ThreadOneThreadOne 0ThreadOne 1ThreadOne 2ThreadOne 3ThreadOne 4Completed printing Numbers for ThreadOneStarting to print Numbers for ThreadTwoThreadTwo 0ThreadTwo 1ThreadTwo 2ThreadTwo 3ThreadTwo 4Completed printing Numbers for ThreadTwo
在这里,我们看到即使两个线程同时运行,只有一个线程一次进入synchronized方法,在这种情况下是ThreadOne。一旦完成执行,ThreadTwo就可以执行printNumbers方法
5.同步块
多线程的主要目的是尽可能并行地执行任意数量的任务。但是,同步限制了必须执行同步方法或块的线程的并行性。
但是,我们可以尝试通过在同步范围内保留尽可能少的代码来减少以同步方式执行的代码量。可能有许多场景,不是在整个方法上同步,而是可以在方法中同步几行代码。
我们可以使用synchronized块来包含代码的那部分而不是整个方法。也就是说对于需要同步的代码块进行同步,而不是对整个方法进行同步。
由于在同步块内部执行的代码量较少,因此每个线程都会更快地释放锁定。结果,其他线程花费更少的时间等待锁定并且代码吞吐量大大增加。
让我们修改前面的例子,只同步for循环打印数字序列,实际上,它是我们示例中应该同步的唯一代码部分:
public class SynchronizedBlockExample {public void printNumbers {System.out.println("Starting to print Numbers for " + Thread.currentThread.getName);synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread.getName + " " + i);}}System.out.println("Completed printing Numbers for " + Thread.currentThread.getName);}}
运行结果:
Starting to print Numbers for ThreadOneStarting to print Numbers for ThreadTwoThreadOne 0ThreadOne 1ThreadOne 2ThreadOne 3ThreadOne 4Completed printing Numbers for ThreadOneThreadTwo 0ThreadTwo 1ThreadTwo 2ThreadTwo 3ThreadTwo 4Completed printing Numbers for ThreadTwo
尽管ThreadTwo在ThreadOne完成其任务之前“开始”打印数字似乎令人担忧,这只是因为我们在停止ThreadTwo锁之前,允许线程通过System.out.println("Completed printing Numbers for " + Thread.currentThread.getName)语句。
这很好,因为我们只想同步每个线程中的数字序列。我们可以清楚地看到两个线程只是通过同步for循环以正确的顺序打印数字。
6.结论
在这个例子中,我们看到了如何在Java中使用synchronized关键字来实现多个线程之间的同步。我们还通过例子了解了何时可以使用synchronized方法和块。
与往常一样,您可以找到此示例中使用的代码
来源: http://www.spring4all.com/article/15139
右上角按钮分享给更多人哦~
来都来了,点个在看再走吧~~~