资讯详情

Java进阶基础

一、多线程

流程:程序执行过程,正在运行的程序。作为资源分配的单位

线程:程序内部的执行路径。作为调度和执行的单位,每个线程都有独立的运行栈和程序计数器。

单核CPU:一种假多线程,切换执行

并发:一个CPU使用时间片同时执行对个任务

并行:多个CPU同时执行多个任务

  • 程序需要同时执行两个或多个任务
  • 程序需要实现用户输入、文件读写操作、网络操作、搜索等一些等待任务
  • 当需要一些后台操作程序时

方法一:继承Thread类

  • 创造继承Thread类的子类
  • 重写Thread类的run()方法
  • 重写Thread子类对象
  • 调用此对象start()->功能:启动当前线程;调用当前线程run()方法

方法二:实现Runnable接口

  • 创建一个实现了Runnable接口的类
  • 实现类实现Runnable抽象法:run()
  • 创建实现对象
  • 将这个对象作为参数传递Thread在类结构中,创建Thread类的对象
  • 通过Thread调用类对象start()

比较方法一、二:

  • 实现方单继承的局限性
  • 实现多线程共享数据的方法更适合处理

方法三:实现Callable接口

比较方法二、三:

call()可有返回值

call()可以抛出异常,通过外部操作捕获异常信息

Callable支持泛型

方法四:使用线程池

  • 提供指定线程数量的线程池
  • 需要实现指定线程的操作Runnable接口或Callable接口实现类对象
  • 关闭连接池

好处:

  • 提高响应速度,减少创建新线程的时间
  • 减少资源消耗,重复使用线程池中线程,无需每次创建
  • 便于线程管理
    • corePoolSize:核心池的大小
    • maxmumPoolSize:最大线程数
    • keepAliveTime:当没有任务时,最多可以停止多长时间

  • start():功能:启动当前线程;调用当前线程run()方法
  • run():需要重写Thread该方法将创建的线程的操作声明
  • currentThread():静态方法,返回执行当前代码的线程
  • getName():获取当前线程的名称
  • setName():设置当前线程的名字
  • yield():释放当前CPU的执行权
  • jion():在线程a中调用线程bjoin()方法,此时线程a将进入阻塞状态,直到线程b完全执行,线程a将结束阻塞状态join异常会在方法中抛出,所以我们还需要try-catch捕捉异常处理
  • sleep():sleep()方法中的形参long millitime,调用此方法将使当前线程睡眠指定millitime(毫秒),指定millitime在毫秒内,当前线程处于阻塞状态
  • isAlive():判断当前线程是否存活,如果当前线程存活,则返回true,若消亡,返回false

获取当前线程的优先级:getPriority() 设置当前线程的优先级:setPriority(int p),p取值范围为1~10 说明:高优先级线程在概率上会有更高的概率抢占低优先级线程cup执行权并不意味着只有高优先线程执行后,才能执行低优先线程。

MAX_PRIORITY:10(最高优先级) MIN_PRIORITY:(最低优先级) NORM_PRIORITY:5(默认优先级)

新建状态(New):Thread t = new MyThread()

就绪状态(Runnable):调用线程对象时start()方法,线程即进入就绪状态。线程处于就绪状态,只是表明线程已经准备好等待CPU调度执行并不意味着执行t.start()此线程将立即执行

运行状态(Running):当CPU当调度线程处于就绪状态时,线程可以真正执行,即进入运行状态

阻塞状态(Blocked):由于某种原因,在运行状态下的线程暂时放弃CPU停止执行使用权,此时进入阻塞状态,直到进入就绪状态,才有机会再次被执行CPU调用进入运行状态。

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

  • 等待阻塞:在运行状态下执行线程wait()使线程进入等待阻塞状态的方法
  • 同步阻塞:线程正在获取synchronized同步失败(因为锁被其他线程占用),会进入同步阻塞状态
  • 其他阻塞:通过调用线程的sleep()或join()或发出I/O当要求时,线程将进入阻塞状态。sleep()状态超时,join()等待线程终止或超时I/O处理完毕后,线程再次转移到就绪状态

死亡状态(Dead):线程执行完成或因异常退出run()方法,线程结束生命周期。

方法1:同步代码块

sychronized(同步监视器){///同步代码}

  • 操作共享数据的代码,即需要同步的代码
  • 共享数据:多线程共同操作的变量
  • 同步监视器,俗称锁,任何类别的对象都可以作为锁。多个线程必须共用一把锁。可以考虑使用this充当同步监视器

限制:在操作同步代码时,只能参与一个线程

方法二:同步法

如果在一种方法中完全声明共享数据的代码,则该方法同步sychronized

  • 实现同步解决方案Runnable接口的线程安全
  • 使用同步方法解决继承问题Thread线程安全问题->加static,保证唯一性

方式三:Lock锁

  • 实例化ReentrantLock->private ReentrantLock lock = new ReentrantLock();
  • 调用锁定方法lock()
  • 调用解锁方法unlock()

不同的线程占用对方需要的同步资源,不放弃,等待对方放弃,形成线程的死锁->所有线程都处于阻塞状态

解决方法:

  • 特殊算法、原则
  • 尽量减少同步资源的定义
  • 尽量避免嵌套同步

wait(),notify(),notifyAll()

wait(),notify(),notifyAll()三种方法的调用者必须是同步代码块或同步方法中使用同步监控器

sleep()和wait()的区别

  • 使用方面:

sleep方法是Thread线程方法,而wait是Object顶级类方法。 sleep可在任何地方使用,wait只能用于同步方法和同步块。

  • CPU及锁资源释放:

sleep、wait调用后,当前线程将暂停并放弃CPU的执行时间

sleep不会释放当前持有对象的锁资源,到时间后会继续执行

而wait所有的锁都会释放,需要释放notify/notifyAll只有在重新获得对象资源后才能继续执行。

  • 异常捕获方面:

sleep需要捕获或抛出异常

而wait/notify/notifyAll则不需要

二、Java常用类

1、String、StringBuffer、StringBuilder

String:不可变的字符系列

StringBuffer:可变字符序列:线程安全,效率低

StringBuilder:可变字符序列:线程不安全,效率高

底层都使用char[]存储

选择:

  • 如果你想操作少量的数据 String
  • 在多线程操作字符串缓冲区下操作大量数据 StringBuffer
  • 单线程操作字符串缓冲区下操作大量数据 StringBuilder

2、比较器

Comparable:

        String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象的方法

        自定义类需要自己去实现Comparable接口

Comparator:

        临时new 一个接口对象,属于临时性的比较

3、枚举类

类的对象只有有限个,确定的

自定义枚举类:

  • 声明Season对象的属性:private final修饰
  • 私有化类的构造器,并给对象属性赋值
  • 提供当前枚举类的多个对象:public static final的

enum关键字枚举类:

  • 提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
  • 声明Season对象的属性:private final修饰
  • 私有化类的构造器,并给对象属性赋值
  • 提供getter/setter方法

4、注解

框架=注解+反射+设计模式

@Annotation,把该Annotation当成一个修饰符使用

  • 注解声明为@interface
  • 内部定义成员,通常使用value表示
  • 可以指定成员的默认值,使用default定义
  • 如果自定义注解没有成员,表明是一个标识作用
  • 如果注解有成员,在使用注解时,需要指明成员的值

对现有注解进行解释说明的注解

@Target

用于描述注解的范围,即注解在哪用。它说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)等。取值类型(ElementType)有以下几种:

  CONSTRUCTOR:用于描述构造器

  FIELD:用于描述域即类成员变量

  LOCAL_VARIABLE:用于描述局部变量

  METHOD:用于描述方法

  PACKAGE:用于描述包

  PARAMETER:用于描述参数

  TYPE:用于描述类、接口(包括注解类型) 或enum声明

  TYPE_PARAMETER:1.8版本开始,描述类、接口或enum参数的声明

  TYPE_USE:1.8版本开始,描述一种类、接口或enum的使用声明

@Retention

用于描述注解的生命周期,表示需要在什么级别保存该注解,即保留的时间长短。取值类型(RetentionPolicy)有以下几种:

  SOURCE:在源文件中有效(即源文件保留)

  CLASS:在class文件中有效(即class保留)

  RUNTIME:在运行时有效(即运行时保留)

@Documented

用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。它是一个标记注解,没有成员。

@Inherited

用于表示某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

5、集合

集合、数组都是对多个数据进行存储操作的结构,简称java容器

数组(Array):

  • 一旦初始化后,其长度就确定了
  • 一旦定义好,其元素的类型也就确定了
  • 提供的方法有限,对添加删除操作效率不高
  • 数据有序可重复,不能满足无序不可重复的需求

集合:

数组、List、Set、Map相互转换:

package com.example.test;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
public class ConvertorTest {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		testList2Array();
        testArray2List();
        testSet2List();
		testList2Set();
		testSet2Array();
		testArray2Set();
		testMap2Set();
		testMap2List();
	}
 
	private static void testMap2List() {
		
		Map<String, String> map = new HashMap<String, String>();  
        map.put("A", "ABC");  
        map.put("K", "KK");  
        map.put("L", "LV");  
        
		// 将Map Key 转化为List    
        List<String> mapKeyList = new ArrayList<String>(map.keySet());  
        System.out.println("mapKeyList:"+mapKeyList);
        
        // 将Map Key 转化为List    
        List<String> mapValuesList = new ArrayList<String>(map.values());  
        System.out.println("mapValuesList:"+mapValuesList);
        
	}
 
	private static void testMap2Set() {
		
        Map<String, String> map = new HashMap<String, String>();  
        map.put("A", "ABC");  
        map.put("K", "KK");  
        map.put("L", "LV");  
        
        // 将Map 的键转化为Set    
        Set<String> mapKeySet = map.keySet();  
        System.out.println("mapKeySet:"+mapKeySet);
        
        // 将Map 的值转化为Set    
        Set<String> mapValuesSet = new HashSet<String>(map.values());  
        System.out.println("mapValuesSet:"+mapValuesSet);
	}
 
	private static void testArray2Set() {
		
        String[] arr = {"AA","BB","DD","CC","BB"};  
        
        //数组-->Set  
        Set<String> set = new HashSet<String>(Arrays.asList(arr));  
        System.out.println(set);  
	}
 
	private static void testSet2Array() {
		Set<String> set = new HashSet<String>();
		set.add("AA");
		set.add("BB");
		set.add("CC");
		
		String[] arr = new String[set.size()];  
		//Set-->数组  
		set.toArray(arr); 
        System.out.println(Arrays.toString(arr));  
	}
 
	private static void testList2Set() {
		  
		List<String> list = new ArrayList<String>();
		list.add("ABC");
		list.add("EFG");
		list.add("LMN");
		list.add("LMN");
		
		//List-->Set
        Set<String> listSet = new HashSet<String>(list);
        System.out.println(listSet);
	}
 
	private static void testSet2List() {
		 
		Set<String> set = new HashSet<String>();
		set.add("AA");
		set.add("BB");
		set.add("CC");
		
		//Set --> List
        List<String> setList = new ArrayList<String>(set);
        System.out.println(setList);  
	}
 
	private static void testList2Array() {
		//List-->数组  
        List<String> list = new ArrayList<String>();  
        list.add("AA");  
        list.add("BB");  
        list.add("CC");  
        Object[] objects = list.toArray();//返回Object数组  
        System.out.println("objects:"+Arrays.toString(objects));  
        
        String[] arr = new String[list.size()];  
        list.toArray(arr);//将转化后的数组放入已经创建好的对象中  
        System.out.println("strings1:"+Arrays.toString(arr));  
	}
	
	private static void testArray2List() {
		//数组-->List  
        String[] ss = {"JJ","KK"};  
        List<String> list1 = Arrays.asList(ss);  
        List<String> list2 = Arrays.asList("AAA","BBB");  
        System.out.println(list1);  
        System.out.println(list2);  
	}
 
}

6、泛型

 Gneric

在集合中使用泛型

集合接口或集合类在jdk5.0时都修改为带泛型的结构

在实例化集合类时,可以指明具体的泛型类型

7、stream

stream关注的是对数据的运算,与CPU打交道

集合关注的是数据的存储,与内存打交道

  • stream自己不会存储元素
  • stream不会改变源对象。相反,他们会返回一个持有结果的新stream
  • stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

执行流程:

  • stream的实例化
  • 一系列的中间操作(过滤、映射、……)
  • 终止操作

说明:

  • 一个中间操作链,对数据源的数据进行处理
  • 一旦执行终止操作,就执行中间操作链,并产生结果。之后不会再被使用

标签: kk系列连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台