【多线程】线程互斥之synchronized 详解
2016-08-18 22:02
369 查看
定义:
线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
我们都知道保证线程完整执行。则需要对其加锁。使用synchronized关键字。在这里锁的对象理论上可以为任何对象。
代码块同步:
方法同步:
在方法前直接加关键字synchronized。
public synchronized void output2(String name){
int len=name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
注意:该方法锁的是this对象,也就是当前类的实例。
静态方法加锁
注意:该方法锁的是该方法所在的类本身(并非实例)。
以上有这三种用synchronized 的方式。如果我要同时保证方式一和方式二能够同步。则必须保证,两个方法锁的是用一个对象。也就是方式一要用synchronized (this)。加入这时你换成synchronized (obj)那就没有意义了。
当然也要必须保证两个方法都是在同一个类下调用。如果
Outputer outputer1=new Outputer();
Outputer outputer2=new Outputer();
然后用outputer1,outputer2分别调用两种方式,那也起不到锁的作用了。
即:类的同一个实例下,并锁的是同一个对象。才能达到互斥的效果。
同理,由于方式三是锁的类的本身,所以如果方式一和方式三若想同步的话也要锁住类的本身。假如我们还应用synchronized (this),我做了一个测试。
private void init(){
final Outputer outputer=new Outputer();
会发现结果出现了异常。该静态方法并没有得到锁的保护。两个方法没有实现同步互斥。
因为在静态方法中synchronized 是锁的类本身。因此在方式一种也要锁类的本身。实例化出来的对象是没用的。可以锁住类的字节码对象。即
有了上面的介绍,在给大家出个题。
那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
我们都知道保证线程完整执行。则需要对其加锁。使用synchronized关键字。在这里锁的对象理论上可以为任何对象。
代码块同步:
public void output(String name){ int len=name.length(); synchronized(this){ for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } }
方法同步:
在方法前直接加关键字synchronized。
public synchronized void output2(String name){
int len=name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
注意:该方法锁的是this对象,也就是当前类的实例。
静态方法加锁
public static synchronized void output3(String name){ int len=name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); }
注意:该方法锁的是该方法所在的类本身(并非实例)。
以上有这三种用synchronized 的方式。如果我要同时保证方式一和方式二能够同步。则必须保证,两个方法锁的是用一个对象。也就是方式一要用synchronized (this)。加入这时你换成synchronized (obj)那就没有意义了。
当然也要必须保证两个方法都是在同一个类下调用。如果
Outputer outputer1=new Outputer();
Outputer outputer2=new Outputer();
然后用outputer1,outputer2分别调用两种方式,那也起不到锁的作用了。
即:类的同一个实例下,并锁的是同一个对象。才能达到互斥的效果。
同理,由于方式三是锁的类的本身,所以如果方式一和方式三若想同步的话也要锁住类的本身。假如我们还应用synchronized (this),我做了一个测试。
private void init(){
final Outputer outputer=new Outputer();
new Thread(new Runnable(){ public void run(){ while(true){ try { Thread.sleep(10); } catch (Exception e) { } outputer.output3("方法三mdm"); } } }).start(); new Thread(new Runnable(){ public void run(){ while(true){ try { Thread.sleep(10); } catch (Exception e) { } outputer.output("方法一MDM"); } } }).start(); }
public static void main(String[] args) { new TraditionalThreadSynchronized().init(); }
会发现结果出现了异常。该静态方法并没有得到锁的保护。两个方法没有实现同步互斥。
因为在静态方法中synchronized 是锁的类本身。因此在方式一种也要锁类的本身。实例化出来的对象是没用的。可以锁住类的字节码对象。即
synchronized (Outputer.class){ //方法体 }
有了上面的介绍,在给大家出个题。
pulbic class Something(){ public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }
那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
a. x.isSyncA()与x.isSyncB() b. x.isSyncA()与y.isSyncA() c. x.cSyncA()与y.cSyncB() d. x.isSyncA()与Something.cSyncA()
相关文章推荐
- 2.使用synchronized关键字实现多线程的同步和互斥(不同线程同时读写同一数据)
- java多线程详解(3)-线程的互斥与同步
- java并发-多线程之传统线程之互斥技术(Synchronized)(3)
- C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)
- 深入多线程之:解析线程的交会(Thread Rendezvous)详解
- 秒杀多线程系列之⑤ 经典线程之同步 关键段实现互斥
- 线程的同步互斥synchronized
- 线程的互斥操作(运用synchronized线程锁安全)
- 详解使用synchronized解决三个线程依次轮流打印出75个数
- 多线程的使用——中断线程详解(Interrupt)
- 本文一个例子展开,介绍Linux下面线程的操作、多线程的同步和互斥
- 详解多线程的两种实现方式以及4个线程,两个线程对j加1,两个线程对j减1完整代码。
- CCR 编写一个不用创建线程,不用考虑资源互斥的多线程程序
- (Java 多线程系列)java synchronized详解
- boost库中thread多线程详解5——谈谈线程中断
- 线程对象Android 开发之多线程处理、Handler 详解
- 介绍Linux下面线程的操作、多线程的同步和互斥
- .NET组件程序设计 第8章 多线程和并发管理 同步线程_互斥
- 介绍Linux下面线程的操作、多线程的同步和互斥
- java多线程学习一线程安全之内存、synchronized、volatile