内存分配程序:
实例程序1:
public class Test1
{
public static void main(String[] args)
{
String str1 = new String("china");
String str2 = new String("china");
System.out.println(str1.equals(str2)); //String类已经重写了equals方法.
System.out.println(str1==str2); //两块内存空间,两个数值.
String str3 = "china";
String str4 = "china";
System.out.println(str3.equals(str4)); //String类已经重写了equals方法.
System.out.println(str3 == str4); //两块内存空间,但是指向同一块数据区,即指针变量数值相同.
}
}
运行结果:
true false true true
内存分配图示:
实例程序2:(误区,请问double salary在内存当中怎么分配的?)
public class Teacher
{
public double salary; // 对象的实例属性.
public Teacher(double salary)
{
this.salary = salary;
}
public void teach()
{
System.out.println("我是Teacher类!!");
}
//new Teacher(3500.00)
}
误解:double salary由于是数据类型+变量名字,所以是在栈区进行分配的。
呵呵,到底在哪里分配,我们需要看程序运行的时候,一般运行的时候是new Teacher(3500.00),所以是在堆区.
实例程序3:静态属性的理解
package zhangsan.lisi;
/*
* 同一张票卖了2张?这是为什么呢?
* */
class A implements Runnable
{
private static int tickets = 1; //静态数据属于类本身的,由操作系统在数据区域只分配一块内存区域.
@Override
public void run()
{
while (true)
{
if (A.tickets > 0)
{
System.out.printf("线程:%s 正在卖出第%d张票.\n",Thread.currentThread().getName(),A.tickets);
A.tickets -= 1;
}
else
{
System.out.println(A.tickets);
break;
}
}
}
}
public class Test3
{
public static void main(String[] args)
{
A aa1 = new A();
Thread t1 = new Thread(aa1);
t1.setName("售票窗口1线程");
t1.start();
A aa2 = new A();
Thread t2 = new Thread(aa2);
t2.setName("售票窗口2线程");
t2.start();
System.out.println("我是主线程");
}
}
静态的属性之所以在Java当中属于类本身的,是因为静态属性在数据区域只占用一块内存空间.
实例程序4:(静态属性)
package zhangsan.lisi;
class N extends Thread
{
//静态的属性属于类本身的 .
private static int tickets = 100; //第一:你要保证共享数据的资源在内存当中占用一块内存空间.
private static String flag = "block"; //第二:你要保证锁标志位是内存当中的同一个内存空间.
@Override
public void run()
{
while (true)
{
synchronized (flag) //synchronized需要保证锁定的是同一个对象,即程序运行中的同一块内存空间.
{
if (tickets > 0)
{
System.out.printf("线程:%s 正在卖出第%d张票.\n", Thread.currentThread().getName(), tickets);
tickets -= 1;
} else
{
System.out.println(tickets);
break;
}
}
try
{
Thread.sleep(200);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public class Test5
{
public static void main(String[] args)
{
N aa1 = new N();
aa1.start();
N aa2 = new N();
aa2.start();
}
}
运行结果:正确
内存分配:
实例程序5:(静态属性)
package zhangsan.lisi;
/*
* 同一张票卖了2张?这是为什么呢?
* */
class A implements Runnable
{
private static int tickets = 100; //这个地方写不写static无所谓.
@Override
public void run()
{
String lock_lable = "flag"; //静态变量在物理实现上只是在数据区域占用一块内存,所以可以这么写.(利用内存分配的技巧.)
while (true)
{
synchronized (lock_lable) //synchronized需要保证锁定的是同一个对象,即程序运行中的同一块内存空间.
{
if (A.tickets > 0)
{
System.out.printf("线程:%s 正在卖出第%d张票.\n",Thread.currentThread().getName(),A.tickets);
A.tickets -= 1;
}
else
{
System.out.println(A.tickets);
break;
}
}
}
}
}
public class Test3
{
public static void main(String[] args)
{
A aa = new A();
Thread t1 = new Thread(aa);
t1.setName("售票窗口1线程");
t1.start();
Thread t2 = new Thread(aa);
t2.setName("售票窗口2线程");
t2.start();
System.out.printf("我是主线程:%s\n",Thread.currentThread().getName());
}
}
内存分配:
实例程序6:(静态内存)
package zhangsan.lisi;
/*
* 同一张票卖了2张?这是为什么呢?
* */
class A implements Runnable
{
private static int tickets = 100; //这个地方写不写static无所谓.
private static String lock_lable = new String("flag");
@Override
public void run()
{
// String lock_lable = "flag"; //静态变量在物理实现上只是在数据区域占用一块内存,所以可以这么写.(利用内存分配的技巧.)
while (true)
{
synchronized (lock_lable) //synchronized需要保证锁定的是同一个对象,即程序运行中的同一块内存空间.
{
if (A.tickets > 0)
{
System.out.printf("线程:%s 正在卖出第%d张票.\n",Thread.currentThread().getName(),A.tickets);
A.tickets -= 1;
}
else
{
System.out.println(A.tickets);
break;
}
}
}
}
}
public class Test3
{
public static void main(String[] args)
{
A aa = new A();
Thread t1 = new Thread(aa);
t1.setName("售票窗口1线程");
t1.start();
Thread t2 = new Thread(aa);
t2.setName("售票窗口2线程");
t2.start();
System.out.printf("我是主线程:%s\n",Thread.currentThread().getName());
}
}
内存分配: