黑马程序员技术交流社区

标题: 这段程序为什么会内存溢出啊? [打印本页]

作者: 林铁柱    时间: 2012-2-8 10:30
标题: 这段程序为什么会内存溢出啊?
本帖最后由 林铁柱 于 2012-2-14 09:16 编辑

import java.util.Random;


public class MyMain {

        /**
         * @param args
         */
         int panZi = 0;
         Random random  = new Random();
         static MyMain mymain = new  MyMain();
        public static void main(String[] args) {
                mymain.a2();
        }
       
        public void a1(){
                int j=0;
                if(panZi==0){
                        j = random.nextInt(10);
                        if(j>0){
                                panZi  =panZi + j;
                                System.out.println("爸爸放了"+j+"个苹果");
                        }
                }
                mymain.a2();
        }
       
        public  void a2(){
                if(panZi>0){
                        System.out.println("爸爸等着孩子拿苹果");
                        System.out.println("孩子拿走一个苹果");
                        panZi--;
                }
                mymain.a1();
        }
}
作者: 张建银    时间: 2012-2-8 10:48
你这个程序貌似会无限循环下去吧,内存泄漏不就是程序执行完毕,内存中的资源没有被回收吗?
作者: 林铁柱    时间: 2012-2-8 10:50
原题是这样的:
一个爸爸,一个盘子,一个孩子,当盘子是空时,孩子不能拿苹果,爸爸会往里放苹果;当盘子有苹果时,爸爸不能放苹果,孩子每次取一个苹果
盘子空时,孩子只能等着爸爸放好苹果后才能去拿

盘子为空的时候爸爸才能放苹果
保证儿子每次都能拿到苹果

作者: 李泽霖    时间: 2012-2-8 11:31
这是我做的,参照一下
class Testapples
{
public static void main(String[] args)
{
apples a = new apples(100);
new Father(a).start();
new Children(a).start();
}
}
class apples
{
int number=0;
int size;
public apples(int size)
{
this.size = size;
}
boolean available=false;
}



class Father extends Thread
{
apples a = null;
public Father(apples a)
{
this.a = a;
}
public void run()
{
while (a.number < a.size)
{
System.out.println("father puts apples"+(++a.number));
a.available=true;
}
}
}


class Children  extends Thread
{
apples a=null;
int i=0;
public Children(apples a)
{
this.a = a;
}
public void run()
{
while(i<a.size)
{
if(a.available==true && i<a.number)
System.out.println("children get apples"+(++i));
if(i==a.number)
a.available=false;
}
}
}


class Father extends Thread
{
apples a = null;
public producer(apples a)
{
this.a = a;
}
public void run()
{
while (a.number < a.size)
{
System.out.println("procdure puts ticket"+(++t.number));
a.available=true;
}
}
}


class Children  extends Thread
{
apples a=null;
int i=0;
public consumer(apples a)
{
this.a = a;
}
public void run()
{
while(i<a.size)
{
if(a.available==true && i<a.number)
System.out.println("consumer buys ticket"+(++i));
if(i==a.number)
a.available=false;
}
}
}
作者: 李泽霖    时间: 2012-2-8 11:31
这是我做的,参照一下
class Testapples
{
public static void main(String[] args)
{
apples a = new apples(100);
new Father(a).start();
new Children(a).start();
}
}
class apples
{
int number=0;
int size;
public apples(int size)
{
this.size = size;
}
boolean available=false;
}



class Father extends Thread
{
apples a = null;
public Father(apples a)
{
this.a = a;
}
public void run()
{
while (a.number < a.size)
{
System.out.println("father puts apples"+(++a.number));
a.available=true;
}
}
}


class Children  extends Thread
{
apples a=null;
int i=0;
public Children(apples a)
{
this.a = a;
}
public void run()
{
while(i<a.size)
{
if(a.available==true && i<a.number)
System.out.println("children get apples"+(++i));
if(i==a.number)
a.available=false;
}
}
}


class Father extends Thread
{
apples a = null;
public producer(apples a)
{
this.a = a;
}
public void run()
{
while (a.number < a.size)
{
System.out.println("procdure puts ticket"+(++t.number));
a.available=true;
}
}
}


class Children  extends Thread
{
apples a=null;
int i=0;
public consumer(apples a)
{
this.a = a;
}
public void run()
{
while(i<a.size)
{
if(a.available==true && i<a.number)
System.out.println("consumer buys ticket"+(++i));
if(i==a.number)
a.available=false;
}
}
}
作者: 林铁柱    时间: 2012-2-8 11:45
李泽霖 发表于 2012-2-8 11:31
这是我做的,参照一下
class Testapples
{

用多线程做的思路不错,要是能father放一个child哪一个就更好了
作者: 王_涛    时间: 2012-2-8 13:44
这是一个生产者和消费者的问题

实现代码如下:
  1. import java.util.Random;

  2. public class ThreadApple {
  3.         public static void main(String[] args) {
  4.                 //创建一个盘子
  5.                 Plate p = new Plate();
  6.                 //创建两个线程并启动。
  7.                 new Thread(new Father(p)).start();
  8.                 new Thread(new Son(p)).start();
  9.         }
  10. }

  11. //盘子
  12. class Plate {
  13.         private int num = 0;
  14.         private Random ran = new Random();
  15.         public synchronized void put() {
  16.                 while(num > 0) {
  17.                         try {
  18.                                 this.wait();
  19.                         } catch (InterruptedException e) {
  20.                                 e.printStackTrace();
  21.                         }
  22.                 }
  23.                 num = ran.nextInt(10);
  24.                 System.out.println(Thread.currentThread().getName() + "爸爸向盘子里放了" + num + "个苹果");
  25.                 this.notify();
  26.         }
  27.         public synchronized void get() {
  28.                 while(num == 0) {
  29.                         try {
  30.                                 this.wait();
  31.                         } catch (InterruptedException e) {
  32.                                 e.printStackTrace();
  33.                         }
  34.                 }
  35.                 num--;
  36.                 System.out.println(Thread.currentThread().getName() + "孩子从盘子里取出一个苹果,盘子里还剩下" + num + "个苹果");
  37.                 this.notify();
  38.         }
  39. }

  40. //爸爸线程,向盘子里放苹果。
  41. class Father implements Runnable {
  42.         private Plate p;
  43.         public Father(Plate p) {
  44.                 this.p = p;
  45.         }
  46.         public void run() {
  47.                 while(true) {
  48.                         p.put();
  49.                 }
  50.         }
  51. }

  52. //孩子线程,从盘子里取苹果。
  53. class Son implements Runnable {
  54.         private Plate p;
  55.         public Son(Plate p) {
  56.                 this.p = p;
  57.         }
  58.         public void run() {
  59.                 while(true) {
  60.                         p.get();
  61.                 }
  62.         }
  63. }
复制代码

作者: 最初的理想    时间: 2012-2-8 15:16
这是经典的消费者生产者的问题哦,本意就是考察线程的互斥同步嘛,get put方法中的while循环是为了防止出现假唤醒,当然用if也可以,老实说我自己做最多用if语句,绝对想不到用while,假唤醒的情况不是很熟悉。
作者: 林铁柱    时间: 2012-2-8 17:18
王_涛 发表于 2012-2-8 13:44
这是一个生产者和消费者的问题

实现代码如下:

对,就是这个。。看来我该晚上补补课了。。。╮(╯▽╰)╭
作者: 蒋昌宏    时间: 2012-2-14 01:14
我是来蹭分的。。。
作者: 李杨    时间: 2012-2-14 03:15
本帖最后由 李杨 于 2012-2-14 03:36 编辑

这道题很有意思,a1调用a2,a2调用a1,互相调用。

在堆栈中两个方法互相调用,a1调用a2的时候在栈中开辟运行空间,a2调用a1时开辟运行空间,就是两个方法在互相调用对方不断的在堆中开辟内存空间,

根据盘子的随机数,来让执行a1方法,a1执行完毕后又开始调用a2,a2又给盘子一个随机数,然后又开始调用a1方法。

周而复始,最终导致堆栈内存溢出。
作者: 李杨    时间: 2012-2-14 03:16
类似于递归。。呵呵。。补充。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2