java多线程的等待唤醒机制及如何解决同步过程中的安全问题

/*
class Person{
String name;
String sex;
boolean flag = true;
public void setPerson(String name, String sex){
this.sex=sex;
this.name=name;
}
}
class Input implements Runnable{
int x=0;
Person p;
Input(Person p){
this.p=p;
}
public void run(){
while(true){
if(x==1){
p.setPerson("hjz", "man");
}
else p.setPerson("哈哈哈", "女女女女");
x=(x+1)%2;
}
}
} class Output implements Runnable{
int x=0;
Person p;
Output(Person p){
this.p=p;
}
public void run(){
while(true){
System.out.println(p.name + "....." + p.sex);
}
}
}
public class Test{
public static void main(String[] args){
Person p = new Person();
new Thread(new Input(p)).start();
new Thread(new Output(p)).start();
}
}
*/ /*
输出的结果:
哈哈哈.....man
hjz.....man
hjz.....man
哈哈哈.....man
hjz.....女女女女
*/ //线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
/*
class Person{
String name;
String sex;
boolean flag = true;
public void setPerson(String name, String sex){
this.sex=sex;
this.name=name;
}
} class Input implements Runnable{
int x=0;
Person p;
Input(Person p){
this.p=p;
}
public void run(){
while(true){
synchronized(new Object()){
if(x==1){
p.setPerson("hjz", "man");
}
else p.setPerson("哈哈哈", "女女女女");
x=(x+1)%2;
}
}
}
} class Output implements Runnable{
int x=0;
Person p;
Output(Person p){
this.p=p;
}
public void run(){
while(true){
System.out.println(p.name + "....." + p.sex);
}
}
}
public class Test{
public static void main(String[] args){
Person p = new Person();
new Thread(new Input(p)).start();
new Thread(new Output(p)).start();
}
}
*/ //同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
//本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
/* class Input implements Runnable{
int x=0;
Person p; Input(Person p){
this.p=p;
}
public void run(){
while(true){
synchronized(p){
if(p.flag){
try{
p.wait();
}catch(InterruptedException e){
}
}
if(!p.flag){
if(x==1){
p.setPerson("hjz", "man");
}
else p.setPerson("哈哈哈", "女女女女");
x=(x+1)%2;
} p.flag=true;
p.notify(); }
}
}
} */ //现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
//调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
class Person{
String name;
String sex;
boolean flag = true;
public void setPerson(String name, String sex){
synchronized(this){
if(!flag){
try{
wait();
}catch(InterruptedException e){}
}
if(flag){
this.sex=sex;
try{
Thread.sleep(100);
}catch(InterruptedException e){}
this.name=name;
}
flag=false;
notify();
}
} public void outPerson(){
synchronized(this){
if(flag){
try{
wait();
}catch(InterruptedException e){}
}
if(!flag){
System.out.println(name + "....." + sex);
}
flag=true;
notify();
}
}
} class Input implements Runnable{
int x=0;
Person p; Input(Person p){
this.p=p;
}
public void run(){
while(true){
if(x==1){
p.setPerson("hjz", "man");
}
else p.setPerson("哈哈哈", "女女女女");
x=(x+1)%2;
}
}
} class Output implements Runnable{
int x=0;
Person p;
Output(Person p){
this.p=p;
}
public void run(){
while(true){
p.outPerson();
}
}
} public class Test{
public static void main(String[] args){
Person p = new Person();
new Thread(new Input(p)).start();
new Thread(new Output(p)).start();
}
}

  

上一篇:Mybatis根据表自动生成相关代码


下一篇:sqlserver 关于快照