一、多线程
- 工厂模式
- 单利模式
- 代理模式
1.单例模式(Singleton):
注意:
- 单例类只能有一个实例
- 单利必须自己创建自己的唯一实例
- 单例类必须含有所有其他对象提供这一实例
2.饿汉式单利
public class Calendar {
private final static Calendar CALENDAR = new Calendar ();
private Calendar(){};
public static Calendar getInstance(){
return CALENDAR;
}
}
3.懒汉式单利
public class Calendar2 {
//需要一个静态的成员变量保存咋们的实例;
private static Calendar2 CALENDAR2 ;
//私有化构造器,不让外边new;
private Calendar2(){};
//持有一个方法,这个方法能返回内存当中的实例;
public static Calendar2 getInstance(){
if (CALENDAR2 == null){
CALENDAR2 = new Calendar2 ();
}
return CALENDAR2;
}
}
4.字符串变成数组统计中元素的个数
package com.xinzhi;
import java.util.HashMap;
import java.util.Map;
/**
* @author:荆少奇
* @create:2020/11/7 16:04
*
*/
public class Test1 {
public static void main(String[] args) {
String content = "hello world hello world aa" + "bb cc db cc ww qq xx xxx";
//1.先全部搞成小写
content = content.toLowerCase ();
//2.字符串搞成数组
String[] worlds = content.split ("");
//3.创建一个hashmap保存结果
Map<String,Object> result = new HashMap<> (16);
//4.循环遍历数据一个单词一个单词看
for (String word:worlds){
//看一看hasmap里有没有这个key
//有的话value+1
if(result.containsKey (word)){
result.put (word,(Integer)result.get (word) + 1);
}else{
//没有的话放进去(word+1)
result.put (word,1);
}
//hashmap便利
for(Map.Entry<String, Object> entry:result.entrySet ()){
System.out.println (entry.getKey () + "出现" + entry.getValue () + "次了");
}
}
}
}
5.归并的思想和对比
package com.xinzhi;
/**
* @author:荆少奇
* @create:2020/11/7 15:15
*/
public class Test {
public static void main(String[] args) {
int[] arr1 = {1,3,5};
int[] arr2 = {2,4,6};
int[] concat = concat (arr1,arr2);
//把两个有序数组合并成一个数组,还有序
for (int i:concat){
System.out.println (i + " ");
}
}
private static int[] concat(int[] arr1,int[] arr2) {
//1.创建一个新数组
int[] temp = new int[arr1.length + arr2.length];
int left = 0;
int right = 0;
int newIndex = 0;
//退出循环的机制
while (arr1.length != left && arr2.length != right){
if (arr1[left] > arr2[right]){
temp[newIndex] = arr2[right];
right++;
}else {
temp[newIndex] = arr1[left];
left++;
}
newIndex++;
}
if(arr1.length == left){
for (int i = right; i < arr2.length;i++){
temp[newIndex++] = arr2[i];
}
}
if(arr2.length == right){
for (int i = left; i < arr1.length;i++){
temp[newIndex++] = arr1[i];
}
}
return temp;
}
}
二、多进程
电脑开了很多应用程序,一个程序一个进程
一个进程里边包含很多线程
Thread:
currentThread : 显示当前线程
Thread.sleep: 让线程睡几毫秒
-
start(): 开启一个新的线程
package currentThreadAndThis; public class MyThread extends Thread { public MyThread(){ System.out.println("当前线程的名字:"+Thread.currentThread().getName()); System.out.println("当前线程的名字:"+this.getName()); } @Override public void run(){ System.out.println("当前线程的名字:"+Thread.currentThread().getName()+" run=="+Thread.currentThread().isAlive()); System.out.println("当前线程的名字:"+this.getName()+" run=="+this.isAlive()); } } //启动类 package currentThreadAndThis; public class Run { public static void main(String[] args) { MyThread myThread=new MyThread(); //初始化Thread对象,方便调用start(); //此时myThread作为参数传入Thread中,其实是myThread委托thread去执行; Thread thread=new Thread(myThread); //初始化自定义线程名称 thread.setName("C"); //启动线程 thread.start(); } }
运行结果
- 当前线程的名字:main
- 当前线程的名称:Thread-0
- 当前线程的名字:C run == tru
- 当前线程的名字:Thread-0 run ==false**
并发
同时拥有两个或多个线程,如果程序在单核处理器上运行,多个线程将交替地换入或者换出内存,这些线程是同时「 存在 」的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,此时,程序中每个线程都将分配到一个处理器核上,因此可以同时运行。并发就是多个线程操作相同的物理机中的资源,保证其线程安全,合理的利用资源。
三、线程安全问题初探(vector和hashTap)
1.异常
顶级父类:Throwable
Error 错误 :一旦发生错误程序就直接崩溃
Exception 异常:异常分为受查异常和运行时异常
受查异常:手动提前处理
运行时异常:手动做好检查
1. 返回异常发生时的详细信息
public string getMessage();
2. 返回异常发生时的简要描述
public string toString();
3. 返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以声称本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同
public string getLocalizedMessage();
4. 在控制台上打印Throwable对象封装的异常信息
public void printStackTrace();
四、Exception:异常
1.处理异常
1. 抛出异常(throws):当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
2. 捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。
try{
}catch{
}
printStackTrace:能打出异常在哪
2.throws和throw有什么不同
位置不同:throws用在函数上,后面跟的是异常类,可以跟多个。
throw用在函数内,后面跟的是异常对象。
功能不同:throws用来声明异常,让调用者知道该功能有可能出现的问题,并由调用者给出预先的处理方式。
throw抛出具体问题的对象。语句执行到throw功能就结束了,跳转到调用者。并将具体的问题对象抛给调用者。
注意:throw语句独立存在,下面不要定义其他语句。因为执行不到throw下面的语句。
3.线程安全
线程安全是指多个线程在执行同一段代码的时候采用加锁机制,使每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性。
线程不安全就是不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
4.解决多线程不安全的问题:
synchronizd:同步锁
1)同步代码块:
synchronized(同步锁)
{
//方法体
}
(2)同步方法:给多线程访问的成员方法加上synchronized修饰符
public synchronized void test(){
//方法体
}
5.String,StringBuilder,StringBuffer
运行速度:
StringBuilder > StringBuffer > String
在线程安全上:
StringBuilder是线程不安全的,而StringBuffer是线程安全的
- String:适用于少量的字符串操作的情况
- StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
- StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
[图片上传失败...(image-d54150-1604755558371)]
[图片上传失败...(image-4c8640-1604755558371)]
[图片上传失败...(image-d30ab2-1604755558371)]
[图片上传失败...(image-d8c778-1604755558371)]