JAVA synchronized关键字锁机制(中)
2017-09-20 12:08
405 查看
synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选。 下面总结其特性以及使用技巧,加深对其理解。
特性:
1. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
2. 当一个线程同时访问object的一个synchronized(this)同步代码块时,其它线程仍然可以访问非修饰的方法或代码块。
3. 当多个线程同时访问object的[b]synchronized(this)同步代码块时,会存在互斥访问,其它线程会阻塞直到获取锁。[/b]
[b] 4. 当线程访问[b]object的[b]synchronized(this)同步代码块时,同一个线程可以多次获取锁,当然也不需要释放多次。获取和释放必须相同。[/b][/b][/b]
[b][b][b] 5. 所有的对象都可以获取锁,也可以释放锁。[/b][/b][/b]
[b][b][b] 6. 所有的类也可以获取锁和释放锁,因此静态方法也可以加锁。而特性同上。[/b][/b][/b]
猜想:
在jvm中对每个对象都有一个记录锁的状态,当同一个线程访问锁时候就会累加,其它线程访问要等到状态变为未锁状态,当让相同线程释放锁会累减。
质疑:
那么对于类锁来说,应该是所有对象都可以获取锁,那么锁是全局的对所有对象都有效?
结果:
分析结果可以看出对于静态方法加锁,所有的线程调用方法,不管怎样都会互斥,而为加锁不会互斥。
因此:
对于类锁来说应该在持久代也就是方法区有对具体类也有加锁机制,而且原理同对象锁。
那么:
可见,上面可以做如下修改达到相同效果。
结果:
特性:
1. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
2. 当一个线程同时访问object的一个synchronized(this)同步代码块时,其它线程仍然可以访问非修饰的方法或代码块。
3. 当多个线程同时访问object的[b]synchronized(this)同步代码块时,会存在互斥访问,其它线程会阻塞直到获取锁。[/b]
[b] 4. 当线程访问[b]object的[b]synchronized(this)同步代码块时,同一个线程可以多次获取锁,当然也不需要释放多次。获取和释放必须相同。[/b][/b][/b]
[b][b][b] 5. 所有的对象都可以获取锁,也可以释放锁。[/b][/b][/b]
[b][b][b] 6. 所有的类也可以获取锁和释放锁,因此静态方法也可以加锁。而特性同上。[/b][/b][/b]
猜想:
在jvm中对每个对象都有一个记录锁的状态,当同一个线程访问锁时候就会累加,其它线程访问要等到状态变为未锁状态,当让相同线程释放锁会累减。
质疑:
那么对于类锁来说,应该是所有对象都可以获取锁,那么锁是全局的对所有对象都有效?
public class SynchronizedMtdTest { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { SynchronizedMtdTest.appendStr(); } }).start(); new Thread(new Runnable() { @Override public void run() { SynchronizedMtdTest.printStr(); } }).start(); new Thread(new Runnable() { @Override public void run() { SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest(); synchronizedMtdTest.appendStr(); } }).start(); new Thread(new Runnable() { @Override public void run() { SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest(); synchronizedMtdTest.printStr(); } }).start(); new Thread(new Runnable() { @Override public void run() { SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest(); synchronizedMtdTest.append(); } }).start(); } public synchronized static void appendStr() { System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------"); try { Thread.sleep(1000); System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void append() { System.out.println("pid=" + Thread.currentThread().getId() + "------append------"); try { Thread.sleep(3000); System.out.println("pid=" + Thread.currentThread().getId() + "------append3000------"); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized static void printStr() { System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------"); try { Thread.sleep(6000); System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------"); } catch (InterruptedException e) { e.printStackTrace(); } } }
结果:
pid=10------appendStr------ pid=14------append------ pid=10------appendStr1000------ pid=13------printStr------ pid=14------append3000------ pid=13------printStr6000------ pid=12------appendStr------ pid=12------appendStr1000------ pid=11------printStr------ pid=11------printStr6000------
分析结果可以看出对于静态方法加锁,所有的线程调用方法,不管怎样都会互斥,而为加锁不会互斥。
因此:
对于类锁来说应该在持久代也就是方法区有对具体类也有加锁机制,而且原理同对象锁。
那么:
可见,上面可以做如下修改达到相同效果。
public static void appendStr() { synchronized (SynchronizedMtdTest.class) { System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------"); try { Thread.sleep(1000); System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------"); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void printStr() { synchronized (SynchronizedMtdTest.class) { System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------"); try { Thread.sleep(6000); System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------"); } catch (InterruptedException e) { e.printStackTrace(); } } }
结果:
pid=10------appendStr------ pid=10------appendStr1000------ pid=13------printStr------ pid=13------printStr6000------ pid=12------appendStr------ pid=12------appendStr1000------ pid=11------printStr------ pid=11------printStr6000------
相关文章推荐
- 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线程同步机制synchronized关键字的理解
- Java的synchronized关键字:同步机制总结
- Java学习笔记79. 多线程的同步机制 -- synchronized 关键字