您的位置:首页 > 其它

多线程实现互斥访问对象的方法

2017-11-29 23:21 351 查看

场景说明

假设有 A、B 两个线程都去调用对象 α 的方法 method1(),并且要求 A、B 两个线程是互斥调用 method1 的。具体来说,假设 method1 中有 4 个命令,一旦 A 调用了 method1,在执行 method1 中有 4 个命令的时候,B 不会调用 method1 方法,反之,依然。

利用 java的同步机制

在 JAVA 中的 Object 类型中,都是带有一个内存锁的,在有线程获取该内存锁后,其它线程无法访问该内存,从而实现JAVA中简单的同步、互斥操作。具体到代码中,涉及到三个关键字:

synchronize:这个关键字会实现对象的方法互斥的执行

notify:通知另外一个正在等待进程可以申请资源

wait:本线程主动释放资源

notify、wait 实现了线程间的通信

经常被锁的资源为:

字节码:对象的 class,例如,A.class

类中的 static 类型的对象

或者在 main 方法中 new 一个对象

第一种代码的实现

package wyf.org.concurrent.KeyWord;

public class Word implements Runnable {
private String name ;
private int count = 0 ;
public Object o ;
public Word(String name, Object o){
this.name = name;
this.o = o ;
}

public  void output() throws InterruptedException{

synchronized(o){
o.notify();//当程序走到这里,会先执行 notify 的操作,无论是 a 或者 b 都会得到 o 的锁并且执行下面的 5 行代码,最后 wait 主动让出 o 的锁
System.out.println(name +  " 1, thread run ");
Thread.sleep(1000);
System.out.println(name +  " 2, thread run ");
System.out.println(name +  " 3, thread run ");
System.out.println(" ");
o.wait();
}
}
public static void main(String[] args) {

/*
* 使用一个 object 来作为同步的的临界值,哪个线程得了 object 的锁就能,活得 synchronized 中代码的执行资源
* */
Object o = new Object();
Word a = new Word("A",o);
Word b = new Word("B",o);
new Thread(a).start();
new Thread(b).start();
}

public void run() {
while(true){
try {
this.output();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


下面是程序运行的时序图:



第二种代码的实现

package wyf.org.concurrent.KeyWord;

public class SynchroniseWord implements Runnable{

private String name = "";
public SynchroniseWord(String name){
this.name = name ;
}
public synchronized void Count() throws InterruptedException{
System.out.println(name +  " 1, thread run ");
Thread.sleep(1000);
System.out.println(name +  " 2, thread run ");
System.out.println(name +  " 3, thread run ");
System.out.println(" ");
}

public void run() {
while(true){
try {
this.Count();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SynchroniseWord sw = new SynchroniseWord("A");
new Thread(sw).start();
new Thread(sw).start();
}
}


程序运行的时序图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐