在本代码的Info类里面分别定义了一个set同步方法和一个get同步方法 程序从main方法开始运行,然后执行new Thread(pro).start()和new Thread(con).start()以后在同一时间会分别执行Producer类和Consumer类的run()方法 而此时Producer类里的run()方法会调用Info类里面的set()方法,而Consumer类里的run()方法会调用Info类里面的get()方法, (我是这么认为的) 虽然set()方法和get()方法都是同步方法 但是在两个方法执行的过程当中如果在set()方法里执行到this.setName(name)以后此时get()方法开始执行并且没有等到set()方法执行完就已经提前结束 那么会出现content的值为null的现象 可是此代码是不会出现这种情况呢 这是为什么??????!!! class Info{ // 定义信息类
private String name = "李兴华"; // 定义name属性
private String content = "JAVA讲师" ; // 定义content属性
public synchronized void set(String name,String content){
this.setName(name) ; // 设置名称
try{
Thread.sleep(300) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
this.setContent(content) ; // 设置内容
}
public synchronized void get(){
try{
Thread.sleep(300) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
System.out.println(this.getName() +
" --> " + this.getContent()) ;
}
public void setName(String name){
this.name = name ;
}
public void setContent(String content){
this.content = content ;
}
public String getName(){
return this.name ;
}
public String getContent(){
return this.content ;
}
};
class Producer implements Runnable{ // 通过Runnable实现多线程
private Info info = null ; // 保存Info引用
public Producer(Info info){
this.info = info ;
}
public void run(){
boolean flag = false ; // 定义标记位
for(int i=0;i<50;i++){
if(flag){
this.info.set("李兴华","JAVA讲师") ; // 设置名称
flag = false ;
}else{
this.info.set("mldn","www.mldnjava.cn") ; // 设置名称
flag = true ;
}
}
}
};
class Consumer implements Runnable{
private Info info = null ;
public Consumer(Info info){
this.info = info ;
}
public void run(){
for(int i=0;i<50;i++){
this.info.get() ;
}
}
};
public class ThreadCaseDemo02{
public static void main(String args[]){
Info info = new Info(); // 实例化Info对象
Producer pro = new Producer(info) ; // 生产者
Consumer con = new Consumer(info) ; // 消费者
new Thread(pro).start() ;
new Thread(con).start() ;
}
};
private String name = "李兴华"; // 定义name属性
private String content = "JAVA讲师" ; // 定义content属性
public synchronized void set(String name,String content){
this.setName(name) ; // 设置名称
try{
Thread.sleep(300) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
this.setContent(content) ; // 设置内容
}
public synchronized void get(){
try{
Thread.sleep(300) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
System.out.println(this.getName() +
" --> " + this.getContent()) ;
}
public void setName(String name){
this.name = name ;
}
public void setContent(String content){
this.content = content ;
}
public String getName(){
return this.name ;
}
public String getContent(){
return this.content ;
}
};
class Producer implements Runnable{ // 通过Runnable实现多线程
private Info info = null ; // 保存Info引用
public Producer(Info info){
this.info = info ;
}
public void run(){
boolean flag = false ; // 定义标记位
for(int i=0;i<50;i++){
if(flag){
this.info.set("李兴华","JAVA讲师") ; // 设置名称
flag = false ;
}else{
this.info.set("mldn","www.mldnjava.cn") ; // 设置名称
flag = true ;
}
}
}
};
class Consumer implements Runnable{
private Info info = null ;
public Consumer(Info info){
this.info = info ;
}
public void run(){
for(int i=0;i<50;i++){
this.info.get() ;
}
}
};
public class ThreadCaseDemo02{
public static void main(String args[]){
Info info = new Info(); // 实例化Info对象
Producer pro = new Producer(info) ; // 生产者
Consumer con = new Consumer(info) ; // 消费者
new Thread(pro).start() ;
new Thread(con).start() ;
}
};
解决方案 »
- RMI中怎么会自动把IP从内网映射到外网啊??
- swing jtree 图片抖动的问题
- 为什么日期转换不符啊
- 在JAVA中有没有改变显示器分辨率的技术,请高手们指教,能不能给发点代码?
- FileRead,FileinputStream和RandomAccessFile有什么区别
- 帮帮忙!!
- 关于哈夫曼树的问题(急用)
- 请教一个关于显示字符串的问题,郁闷中,高人请进
- ***********关于Socket的问题,大家都来帮忙看看*************
- Java程序可否在Windows下和Linux下绑定为可执行的exe程序?
- 请问一下AWT中鼠标事件转移的问题
- 如何用java模拟Fn+F6组合键
new Thread(con).start() ;
看看线程的执行顺序,是先执行set再执行get,不会出现你说的现象。get永远都能得到值,如果你把上面的反过来写,那么它永远都只能得到一个值“李兴华 --> JAVA讲师”
private TestWaitAndNotify twn;
public Productor(TestWaitAndNotify twn) {
this.twn = twn;
}
@Override
public void run() {
for(int i=0; i<5; i++) {
twn.writeCount();
}
}
}class Consumer implements Runnable {
private TestWaitAndNotify twn;
public Consumer(TestWaitAndNotify twn) {
this.twn = twn;
}
@Override
public void run() {
for(int i=0; i<5; i++) {
twn.readCount();
}
}
}public class TestWaitAndNotify {
private int count = 1;
public synchronized void writeCount() {
try {
wait(200); // waiting for consumer
} catch (InterruptedException e1) {
e1.printStackTrace();
}
notify();
count += 1;
System.out.println(" -->> Productor: " + count);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void readCount() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" -->> Consumer: " + count);
notify();
}
public static void main(String[] args) {
final TestWaitAndNotify twn = new TestWaitAndNotify();
Thread p = new Thread(new Productor(twn));
Thread c = new Thread(new Consumer(twn));
p.start();
c.start();
}}
console result: -->> Productor: 2
-->> Consumer: 2
-->> Productor: 3
-->> Consumer: 3
-->> Productor: 4
-->> Consumer: 4
-->> Productor: 5
-->> Consumer: 5
-->> Productor: 6
-->> Consumer: 6
set已经获取了锁但没有释放,get就获取不到锁,就不会执行。
我觉得set()方法和get()方法都是由2个不同的线程分别来调用的 所以不存在取锁和释放的概念!!
给个建议:先看懂书本上的知识,再开始实验。实验是用来加深理解的,不是用来自己猜测的。
http://blog.csdn.net/KingWolfOfSky/archive/2010/04/08/5464990.aspx