10056---Java中Synchronized的用法
来源:互联网 发布:相册制作软件下载 编辑:程序博客网 时间:2024/06/18 17:11
原文:http://blog.csdn.net/luoweifu/article/details/46613015
作者:luoweifu
我们再把SyncThread的调用稍微改一下:
作者:luoweifu
转载请标名出处
《编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程》一文详细讲述了线程、进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础。本文将接着讲一下Java线程同步中的一个重要的概念synchronized.
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
【Demo1】:synchronized的用法
/** * 同步线程 */class SyncThread implements Runnable { private static int count; public SyncThread() { count = 0; } public void run() { synchronized(this) { for (int i = 0; i < 5; i++) { try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } public int getCount() { return count; }}SyncThread的调用:
SyncThread syncThread = new SyncThread();Thread thread1 = new Thread(syncThread, "SyncThread1");Thread thread2 = new Thread(syncThread, "SyncThread2");thread1.start();thread2.start();结果如下:
SyncThread1:0 SyncThread1:1 SyncThread1:2 SyncThread1:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread2:7 SyncThread2:8 SyncThread2:9当两个并发线程(thread1和thread2)访问同一个对象(syncThread)中的synchronized代码块时,在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。Thread1和thread2是互斥的,因为在执行synchronized代码块时会锁定当前的对象,只有执行完该代码块才能释放该对象锁,下一个线程才能执行并锁定该对象。
我们再把SyncThread的调用稍微改一下:
SyncThread syncThread1 = new SyncThread();SyncThread syncThread2 = new SyncThread();Thread thread1 = new Thread(syncThread1, "SyncThread1");Thread thread2 = new Thread(syncThread2, "SyncThread2");thread1.start();thread2.start();
结果如下:
SyncThread1:0 SyncThread2:1 SyncThread1:2 SyncThread2:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread1:7 SyncThread1:8 SyncThread2:9
不是说一个线程执行synchronized代码块时其它的线程受阻塞吗?为什么上面的例子中thread1和thread2同时在执行。这是因为synchronized只锁定对象,每个对象只有一个锁(lock)与之相关联,而上面的代码等同于下面这段代码:
SyncThread syncThread1 = new SyncThread();SyncThread syncThread2 = new SyncThread();Thread thread1 = new Thread(syncThread1, "SyncThread1");Thread thread2 = new Thread(syncThread2, "SyncThread2");thread1.start();thread2.start();这时创建了两个SyncThread的对象syncThread1和syncThread2,线程thread1执行的是syncThread1对象中的synchronized代码(run),而线程thread2执行的是syncThread2对象中的synchronized代码(run);我们知道synchronized锁定的是对象,这时会有两把锁分别锁定syncThread1对象和syncThread2对象,而这两把锁是互不干扰的,不形成互斥,所以两个线程可以同时执行。 2.当一个线程访问对象的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该对象中的非synchronized(this)同步代码块。
【Demo2】:多个线程访问synchronized和非synchronized代码块
class Counter implements Runnable{ private int count; public Counter() { count = 0; } public void countAdd() { synchronized(this) { for (int i = 0; i < 5; i ++) { try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } //非synchronized代码块,未对count进行读写操作,所以可以不用synchronized public void printCount() { for (int i = 0; i < 5; i ++) { try { System.out.println(Thread.currentThread().getName() + " count:" + count); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } public void run() { String threadName = Thread.currentThread().getName(); if (threadName.equals("A")) { countAdd(); } else if (threadName.equals("B")) { printCount(); } }}
调用代码:
Counter counter = new Counter();Thread thread1 = new Thread(counter, "A");Thread thread2 = new Thread(counter, "B");thread1.start();thread2.start();结果如下:
A:0 B count:1 A:1 B count:2 A:2 B count:3 A:3 B count:4 A:4 B count:5上面代码中countAdd是一个synchronized的,printCount是非synchronized的。从上面的结果中可以看出一个线程访问一个对象的synchronized代码块时,别的线程可以访问该对象的非synchronized代码块而不受阻塞。
- 指定要给某个对象加锁
【Demo3】:指定要给某个对象加锁
0 0
- 10056---Java中Synchronized的用法
- Synchronized(一)------java中Synchronized的用法
- java中synchronized的用法
- java中synchronized的用法
- Java中synchronized的用法
- java中synchronized的用法
- java中synchronized的用法
- Java中synchronized的用法
- Java中synchronized的用法
- Java中synchronized的用法
- java中synchronized的用法
- java中synchronized的用法
- Java中Synchronized的用法
- Java中Synchronized的用法
- Java中Synchronized的用法
- Java中Synchronized的用法
- Java中Synchronized的用法
- Java中Synchronized的用法
- java二叉树非递归之前序遍历
- 看完9个笑话 顿悟9个人生道理
- 2016.10.27 函数特性
- 复选框(checkbox)全选/全不选/反选代码
- 2009 Multi-University Training Contest 1 - Host by TJU
- 10056---Java中Synchronized的用法
- IT研发老兵跳槽记之(六):上将伐谋
- ORB-Slam
- 函数作用域
- JSP接收数据
- LeetCode-344. Reverse String-Java
- 使用Fragment代替Activity
- 第一次写博客
- How Many Tables 并查集