java学习(synchronized)
来源:互联网 发布:下载手机app软件 编辑:程序博客网 时间:2024/05/29 23:22
synchronized关键字
作用:
1. 修饰代码块,被修饰的代码块称为同步语句块,其作用范围是{}括起来的代码,作用的对象是调用这个代码块的对象
2. 修饰非静态方法,被修饰的方法称为同步方法,其作用范围是整个方法,作用的对象是调用这个方法的对象
3. 修饰静态方法,其作用范围是整个静态方法,作用的对象是这个类所有的对象
4. 修饰类,其作用的范围是synchronized后面括起来的部分,作用的对象是这个类的所有对象
对代码块加锁
代码
public class ThreadSynchronize implements Runnable { public void run() { synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "synchronized loop" + i); } } } public static void main(String[] args) { ThreadSynchronize t1 = new ThreadSynchronize(); Thread ta = new Thread(t1, "A"); Thread tb = new Thread(t1, "B"); ta.start(); tb.start(); }}
结果
Asynchronized loop0Asynchronized loop1Asynchronized loop2Asynchronized loop3Asynchronized loop4Bsynchronized loop0Bsynchronized loop1Bsynchronized loop2Bsynchronized loop3Bsynchronized loop4
由代码可以得出结论:当两个并发进程访问同一个对象的由synchronized (this)修饰地代码块时,一次只能有一个线程得到这个代码块,另一个必须等待
注意:是两个线程访问同一个对象的,同一个对象的,同一个对象的!
将main函数改为如下如下代码:
ThreadSynchronize t1 = new ThreadSynchronize(); ThreadSynchronize t2 = new ThreadSynchronize(); Thread ta = new Thread(t1, "A"); Thread tb = new Thread(t2, "B"); ta.start(); tb.start();
得到结果
Asynchronized loop0Bsynchronized loop0Asynchronized loop1Bsynchronized loop1Asynchronized loop2Asynchronized loop3Bsynchronized loop2Asynchronized loop4Bsynchronized loop3Bsynchronized loop4
也就是说,当不同线程要访问不同对象的同一个代码块时,synchronized不会起到阻塞效果
代码
public class ThreadSynchronize { public void m4t1() { synchronized (this) { int i = 5; while(i-- > 0){ System.out.println(Thread.currentThread().getName() + ": " + i); try{ Thread.sleep(500); }catch(InterruptedException ie){ } } } } public void m4t2(){ int i =5; while(i-- > 0){ System.out.println(Thread.currentThread().getName() + ": " + i); try{ Thread.sleep(500); }catch(InterruptedException ie){ } } } public static void main(String[] args) { ThreadSynchronize t1 = new ThreadSynchronize(); Thread ta = new Thread(new Runnable() { @Override public void run() { t1.m4t1(); } },"ta"); Thread tb = new Thread(new Runnable() { @Override public void run() { t1.m4t2(); } },"tb"); ta.start(); tb.start(); }}
结果
tb: 4ta: 4tb: 3ta: 3ta: 2tb: 2ta: 1tb: 1tb: 0ta: 0
结果表明:当一个线程访问一个对象的synchronized(this) 代码块时,另一个线程可以访问该对象的非synchronized(this) 修饰的代码块(不同函数中的)
将m4t2()修改得与m4t1()相同,即都用synchronized(this)修饰后,得到结果
ta: 4ta: 3ta: 2ta: 1ta: 0tb: 4tb: 3tb: 2tb: 1tb: 0
结果表明:当一个线程访问到了一个对象的synchronized(this)修饰的代码块时,其他所有线程对该对象的synchronized(this)修饰的代码块的访问都会被阻塞,此时称该线程获取了该对象的对象锁,使得其他线程都不能在此时访问同步代码块
对指定某个对象加锁
public class ThreadSynchronize { public static void main(String[] args) { Account account = new Account("zhangsan", 10000); AccountOperator accountOperator = new AccountOperator(account); final int THREAD_NUM = 5; Thread[] threads = new Thread[THREAD_NUM]; for (int i = 0; i < THREAD_NUM; i++) { threads[i] = new Thread(accountOperator, "Thread" + i); threads[i].start(); } }}class Account { String name; float amount; public Account(String name, float amount) { this.name = name; this.amount = amount; } public void deposit(float amt) { amount += amt; try{ Thread.sleep(100); } catch (InterruptedException e){ } } public void withdraw(float amt) { amount -= amt; try { Thread.sleep(100); } catch(InterruptedException e){ } } public float get() { return amount; }}class AccountOperator implements Runnable { private Account account; public AccountOperator(Account account) { this.account = account; } @Override public void run() { // TODO Auto-generated method stub synchronized(account){ account.deposit(500); account.withdraw(300); System.out.println(Thread.currentThread().getName() + " : " + account.get()); } }}
输出结果
Thread0 : 10200.0Thread3 : 10400.0Thread4 : 10600.0Thread2 : 10800.0Thread1 : 11000.0
在run方法里,我们用synchronized给account对象加了锁,此时,其他想要访问也对account加了锁的区域的线程将会被阻塞
修饰一个非静态方法
public synchronized void run() { // TODO Auto-generated method stub account.deposit(500); account.withdraw(300); System.out.println(Thread.currentThread().getName() + " : " + account.get()); }
表示该方法一次只能让一个对象调用,与之前一个表示方式等价
修饰静态方法
很明显,静态方法是属于类的,因此,静态方法可以保证同一个类的不同实例之间保持同步
public class ThreadSynchronize implements Runnable { public void run() { method(); } public static synchronized void method(){ for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "synchronized loop" + i); } } public static void main(String[] args) { ThreadSynchronize t1 = new ThreadSynchronize(); ThreadSynchronize t2 = new ThreadSynchronize(); Thread ta = new Thread(t1, "A"); Thread tb = new Thread(t2, "B"); ta.start(); tb.start(); }}
输出结果为
Asynchronized loop0Asynchronized loop1Asynchronized loop2Asynchronized loop3Asynchronized loop4Bsynchronized loop0Bsynchronized loop1Bsynchronized loop2Bsynchronized loop3Bsynchronized loop4
修饰一个类
很明显,修饰一个类的时候,该类的所有实例公用同一把锁
参考:http://blog.csdn.net/luoweifu/article/details/46613015
- java学习 synchronized
- Java 线程 synchronized 学习
- java学习(synchronized)
- Java synchronized 学习笔记
- 学习java synchronized的总结
- Java synchronized以及ReentrantLock 学习
- java 多线程编程学习Synchronized
- JAVA多线程学习-synchronized辨析
- Java学习 - synchronized同步机制
- java 中间件学习3-synchronized
- JAVA的synchronized关键字学习
- java之synchronized学习篇
- Java synchronized关键字学习一
- Java synchronized关键字学习二
- Java synchronized详解【推荐学习】
- Java学习 - Thread Synchronized (一)
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- 找试场——世上无难题,只要肯思考_耀晨SYW
- ajax方法的用法
- Linux进程间通信——使用消息队列
- Linux进程间通信——使用共享内存
- 11:字符串、字符数组、字符指针数组
- java学习(synchronized)
- 1064. 朋友数(20)-PAT乙级真题
- android TV遥控器控制GridView不能正常滚动
- Matplotlib学习笔记
- Linux进程间通信——使用信号量
- 洛谷 P1808 单词分类_NOI导刊2011提高(01)
- Python快捷键
- java学习(sort排序方法)
- 1065. 单身狗(25)-PAT乙级真题