上篇博客中简短的回顾了一下基础知识,这篇博客看看SyncThread修饰代码块的实例。
修饰一段代码块
,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。我们看下面一个例子
public class SyncThread implements Runnable{
private static int count;
publicSyncThread() {
count = 0;
}
public void run() {
//加锁的同步代码块
synchronized(this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println(Thread.currentThread().getName() + ":" +(count++));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicint getCount() {
return count;
}
public static void main(String[] args){
SyncThreadsyncThread = new SyncThread();
Threadthread1 = new Thread(syncThread, "SyncThread1");
Threadthread2 = new Thread(syncThread, "SyncThread2");
thread1.start();
thread2.start();
}
}
运行结果:
分析:
当两个并发线程(thread1和thread2)访问同一个对象(syncThread)中的synchronized代码块时,在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。
修改一部分代码:
public static void main(String[] args){
SyncThreadsyncThread1 = new SyncThread();
SyncThreadsyncThread2 = new SyncThread();
Threadthread1 = new Thread(syncThread1, "SyncThread1");
Threadthread2 = new Thread(syncThread2, "SyncThread2");
thread1.start();
thread2.start();
}
结果:这次是一个线程一次交替进行的,这是为什么呢
分析:
这次创建了两个SyncThread的对象syncThread1和syncThread2,线程thread1执行的是syncThread1对象中的synchronized代码(run),而线程thread2执行的是syncThread2对象中的synchronized代码(run); synchronized锁定的是对象,这时会有两把锁分别锁定syncThread1对象和syncThread2对象,而这两把锁是互不干扰的,不形成互斥,所以两个线程可以同时执行。
小结:
Synchronized锁定的是对象,当只实例化一个对象时执行到同步代码块同一时刻只能够有一个线程执行该代码块,如果实例化了多个不同的线程可以调用不同实例化对象中的同步代码块。这应该也就是为什么要使用单例控制类的实例化,可以使线程更加安全。