Java一些记录
2019-02-22
线程安全的优先级高于性能。
Java中的多线程你只要看这一篇就够了 - ImportNew
Java并发编程:volatile关键字解析 - Matrix海子 - 博客园
缓存使用过程中最重要问题是什么时候创建缓存和缓存的失效机制。缓存可以在第一次获取的时候创建也可以在程序启动和缓存失效之后立即创建,缓存的失效可以定期失效,也可以在数据发生变化的时候失效,如果按数据发生变化让缓存失效,还可以分粗粒度失效和细粒度失效。
网站架构的整个演变过程主要是围绕大数据和高并发这两个问题展开的,解决的方案主要分为使用缓存和使用多资源两种类型。多资源主要指多存储(包括多内存)、多CPU和多网络,对于多资源来说又可以分为单个资源处理一个完整的请求和多个资源合作处理一个请求两种类型,如多存储和多CPU中的集群和分布式,多网络中的CDN和静态资源分离。理解了整个思路之后就抓住了架构演变的本质,而且自己可能还可以设计出更好的架构。
无论架构还是协议都要以正确的态度对待,它们都是为了解决特定的问题而设计出来的,我们要认真并且谦虚地学习,不过也不需要将它们当成神圣不可侵犯的东西,它们的本质还是为我们解决问题的工具。另外这些架构、协议以及相关的产品都是经过实际的考验可以解决问题的,不过也并不是说它们就是最优的解决方案,我们只有真正理解了它们所针对的问题才能对它们理解得更透彻、使用得更灵活。
记录类型:域名解析有很多种解析的类型,如常用的A记录和CNAME记录。A记录是将域名解析到IP(一个域名可以有多条A记录),CNAME记录是将域名解析到另一个域名(也就是作为另一个域名的别名),查找时会返回目标域名所对应的IP,
① www.excelib.com 可能会有多条解析记录,而 excelib.com 用一条CNAME记录就可以完成了;②在 www.excelib.com 的IP发生变化时, excelib.com 不需要修改解析内容直接就可以自动改变;③使用CDN时可以将用户直接访问的域名作为一个别名,然后将指向的域名通过ns记录指定CDN专用的DNS服务器进行解析,这样用户访问的域名解析使用的还是正常的DNS服务器但是可以获取到CDN的DNS服务器解析的结果。
Servlet是Server+Applet的缩写,表示一个服务器应用。通过上面的分析我们知道Servlet其实就是一套规范,我们按照这套规范写的代码就可以直接在Java的服务器上面运行。Servlet3.1中Servlet的结构如图6-1所示。
Arrays类为所有基本数据类型的数组提供了一个过载的sort()和binarySearch(),它们亦可用于String和Object。
类加载有三种方式:
- 1、命令行启动应用时候由JVM初始化加载
- 2、通过Class.forName()方法动态加载
- 3、通过ClassLoader.loadClass()方法动态加载
Class.forName()和ClassLoader.loadClass()区别
- Class.forName():将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块;
- ClassLoader.loadClass():只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
- Class.forName(name,initialize,loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象 。
减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。
·无锁并发编程。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一 些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。 ·CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。 ·使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这 样会造成大量线程都处于等待状态。 ·协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。
是值传递。Java语言的方法调用只支持参数的值传递。
String和StringBuilder、StringBuffer的区别?
答:Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer要高。
Java中的线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。用户线程会阻止JVM的正常停止,即JVM正常停止前应用程序中的所有用户线程必须先停止完毕;否则JVM无法停止。而守护线程则不会影响JVM的正常停止,即应用程序中有守护线程在运行也不影响JVM的正常停止。因此,守护线程通常用于执行一些重要性不是很高的任务,例如用于监视其他线程的运行情况。
Java语言中,子线程是否是一个守护线程取决于其父线程:默认情况下父线程是守护线程则子线程也是守护线程,父线程是用户线程则子线程也是用户线程。当然,父线程在创建子线程后,启动子线程之前可以调用Thread实例的setDaemon方法来修改线程的这一属性。
从上述描述可知,一个线程在其整个生命周期中,只可能一次处于NEW状态和TERMINATED状态。而一个线程的状态从RUNNABLE状态转换为BLOCKED、WAITING和TIMED_WAITING这几个状态中的任何一个状态都意味着上下文切换(Context Switch)的产生。
synchronized关键字可以实现操作的原子性,其本质是通过该关键字所包括的临界区(Critical Section)的排他性保证在任何一个时刻只有一个线程能够执行临界区中的代码,这使得临界区中的代码代表了一个原子操作。这一点,读者可能已经很清楚。但是,synchronized关键字所起的另外一个作用——保证内存的可见性(Memory Visibility),也是值得我们回顾的。