版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a2011480169/article/details/86721826
内存分配程序:
实例程序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()); } }
内存分配: