欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于java基础的一些东西

程序员文章站 2024-03-17 19:17:16
...

 最近觉得自己基础方面忘了很多东西,总结 一下

 

 一、关于java类加载器。

      一般会知道java的类加载器是ClassLoader,但是ClassLoader也是java类编写,谁来加载它?肯定不可能是java了,它是

C++编写的BootStrap.BootStrap是嵌套在java虚拟机内核中的,jvm启动的时候它就会启动。

总的来说java虚拟机中默认主要有三个类加载器:BootStrap,ExtClassLoader,AppClassLoader。

当Java虚拟机要加载一个类时,到底该派哪个类加载器去加载呢?

(1) 首先是当前线程的类加载器去加载线程中的第一个类。

(2) 如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器来加载类B。

(3) 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

 

二、Java中stack和heap的区别

java中内存分为两类:stack(堆栈)和heap(堆);

stack是程序内存空间,因此所有基本类型和对象的引用都在stack中

heap是java虚拟机存储对象的,它是一个巨大的内存。当创建一个对象的时候,java虚拟机将对象的引用放在stack中,创建的对象

放在heap中。

所以,基本类型和对象的引用在stack中,对象在heap中。

 

三、java中synchronized加在类上和方法上的区别

     java的synchronized可以加载方法上,也可以加在对象上,从而一段代码只会有一个线程在运行,保证线程同步。是 一种“时间换空间”的做法。

  

public class SyncTest {
public static synchronized void testSyncOnStaticMethod() {

System.out.println(“testSyncOnStaticMethod”);

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

}

public static void testSyncOnClass() {

synchronized (SyncTest.class) {

System.out.println(“testSyncOnClass”);

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

}

}

public synchronized void testSyncOnMethod() {

System.out.println(“testSyncOnMethod”);

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

}

public void testSyncOnThis() {

synchronized (this) {

System.out.println(“testSyncOnThis”);

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

}

}

public static void case1() {

// case1

// 先输出testSyncOnThis或者testSyncOnMethod

// 然后停顿10秒,再输出另一个

// 这个现象表明了

 

// public synchronized void func() {

// }

 

// 等价于

 

// public void func() {

// synchronized (this) {

// }

// }

final SyncTest t1 = new SyncTest();

new Thread(new Runnable() {

@Override

public void run() {

t1.testSyncOnThis();

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

t1.testSyncOnMethod();

}

}).start();

}

public static void case2() {

// case2

// 先输出testSyncOnClass或者testSyncOnStaticMethod

// 然后停顿10秒,再输出另一个

// 这个现象表明了

 

// public synchronized static void staticFunc() {

// }

 

// 等价于

 

// public static void staticFunc() {

// synchronized (SyncTest.class) {

// }

// }

new Thread(new Runnable() {

@Override

public void run() {

SyncTest.testSyncOnClass();

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

SyncTest.testSyncOnStaticMethod();

}

}).start();

}

public static void main(String[] args) {

case1();

case2();

}

}

 从上面的代码我们可以看出synchronized加在方法上本质上还是等价于加在对象上的。

如果synchronized加在一个类的普通方法上,那么相当于synchronized(this)。

如果synchronized加载一个类的静态方法上,那么相当于synchronized(Class对象)。

在使用多线程的时候,知道这个是很关键的,因为synchronized的两种不用用法可能导致两段不相干的代码是互斥的,增加了同步的开销(例如这里的函数testSyncOnThis和testSyncOnMethod,他们在同一个对象this上加了锁),更严重的是可能导致死锁。