package thread_communication;
/*
* 线程间通讯就是多个线程操作同一个资源
* 但是操作动作不同
*
* 同步前提:两个以上线程,操作同一个数据,用同一个锁;
*
* 等待唤醒机制:操作共享数据轮流干活;
* 监视器=锁,wait,notify都是对锁的操作,他们必须在同步中使用,因为只有同步中存在锁;
* 操作时,必须著名针对哪一个锁,因为同步存在嵌套,有各自不同的锁;等待和唤醒必须是同一把锁,而锁可以是任意对象;
* 锁可以是任意对象,所以wait(),notify(),notifyAll()会存在于顶层类Object中;
*
*
* 在synchronized代码被执行期间,线程调用对象的wait()方法,会释放对象锁标志,放弃执行资格,然后进入冻结状态,
* 然后由其它线程调用notify()或者notifyAll()方法通知正在等待的线程。
*
* */
class Res{
private String name;
private String gender;
public void set(String name,String gender){//可以把调用里的同步过程移动到Res类里,变为synchronized函数,
this.gender=gender;
this.name=name;
}
public void print(){//可以把调用里的同步过程移动到Res类里,变为synchronized函数
System.out.println(name+" "+gender);
}
private int mark;//加一个判定,让线程轮流干活,一个线程操作后改变标记值;
public void setmark(int mark){
this.mark=mark;
}
public int gettmark(){
return this.mark;
}
}
class Person_Input implements Runnable{
private Res r;
private Object obj;
private int i=1;
Person_Input(Res r,Object obj){
this.r=r;
this.obj=obj;
}
public void run(){
while(true){//切换
synchronized(obj){//两个动作用同一个锁
if(r.gettmark()==1)
try{obj.wait();}catch(Exception e){}//wait必须在synchronized里,锁之间切换权限;该线程挂起,锁
if(r.gettmark()==0){
if(i==1){
r.set("********LBR********", "Male");
}
else{
r.set("Zhang Yakun", "------Female------");
}
r.setmark(1);
i=(i+1)%2;
obj.notify();//notify必须在synchronized里
}
}
}
}
}
class Person_Output implements Runnable{
private Res r;
private Object obj;
Person_Output(Res r,Object obj){
this.r=r;
this.obj=obj;
}
public void run(){
while(true){
synchronized(obj){
if(r.gettmark()==0)
try{obj.wait();}catch(Exception e){}//wait需要用在同步里;obj这个锁对应的线程等待
if(r.gettmark()==1){
r.print();
r.setmark(0);
obj.notify();//obj对应的锁唤醒
}
}
}
}
}
//--------------------------------------------------------------
public class Ticket {
public static void main(String[] args) {
/*
Res r=new Res();
Object key=new Object();//锁,也可以直接把r当作锁;
Person_Input ri=new Person_Input(r,key);//对同一资源进行操作
Person_Output ro=new Person_Output(r,key);
Thread t1=new Thread(ri);
Thread t2=new Thread(ro);
t1.start();
t2.start();
*/
Res r2=new Res();
Object key2=new Object();
new Thread(new Person_Input(r2,key2)).start();
new Thread(new Person_Output(r2,key2)).start();
}
}
只有两线程的情况下,线程间加锁切换
最新推荐文章于 2022-07-17 21:17:36 发布