0%

Java 线程基础、线程之间的共享和协作 (五)

AQS (AbstractQueuedSynchronizer简称 )

队列同步器AbstractQueuedSynchronizer(以下简称同步器或AQS),是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作

avatar

Read more »

Java 线程基础、线程之间的共享和协作 (四)

CAS(CompareAndSwap)本原理

什么是原子操作?如何实现原子操作?

定义:假定有两个操作A和B(A和B可能都很复杂),如果从执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。
实现原子操作可以使用锁,锁机制,满足基本的需求是没有问题的了,但是有的时候我们的需求并非这么简单,我们需要更有效,更加灵活的机制,

实现原子操作还可以使用当前的处理器基本都支持CAS()的指令,只不过每个厂家所实现的算法并不一样,每一个CAS操作过程都包含三个运算符:一个内存地址V,一个期望的值A和一个新值B,操作的时候如果这个地址上存放的值等于这个期望的值A,则将地址上的值赋为新值B,否则不做任何操作。

Read more »

Java 线程基础、线程之间的共享和协作 (三)

ThreadLocal辨析

与Synchonized的比较

ThreadLocalSynchonized都用于解决多线程并发訪问。

可是ThreadLocal与synchronized有本质的差别。synchronized是利用锁的机制,使变量或代码块在某一时该仅仅能被一个线程訪问。
ThreadLocal为每个线程都提供了变量的副本,使得每个线程在某一时间訪问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享。

Read more »

Java 线程基础、线程之间的共享和协作 (二)

线程的状态

Java中线程的状态分为6种:

  1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

状态之间的变迁如下图所示

avatar

Read more »

Java 线程基础、线程之间的共享和协作 (一)

什么是进程和线程

进程是程序运行资源分配的最小单位

线程是 CPU 调度的最小单位,必须依赖于进程而存在

CPU 核心数和线程数的关系

核心数、线程数:目前主流 CPU 都是多核的。增加核心数目就是为了增加线 程数,因为操作系统是通过线程来执行任务的,一般情况下它们是 1:1 对应关系,也 就是说四核 CPU 一般拥有四个线程。但 Intel 引入超线程技术后,使核心数与线程 数形成 1:2 的关系

CPU 时间片轮转机制

时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法,又称 RR 调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

并行和并发

并发:指应用能够交替执行不同的任务,比如单 CPU 核心下执行多线程并非是 同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不 断去切换这两个任务,已达到”同时执行效果”,其实并不是的,只是计算机的速度太 快,我们无法察觉到而已.

并行:指应用能够同时执行不同的任务,例:吃饭的时候可以边吃饭边打电话, 这两件事情可以同时执行 两者区别:一个是交替执行,一个是同时执行.

当谈论并发的时候一定要加个单位时间,也就是说单位时间内并发量是多少? 离开了单位时间其实是没有意义的。

高并发编程的意义、好处和注意事项

  1. 充分利用 CPU 的资源
  2. 加快响应用户的时间
  3. 可以使你的代码模块化,异步化,简单化

多线程程序需要注意事项

  1. 线程之间的安全性
  2. 线程之间的死锁
  3. 线程太多了会将服务器资源耗尽形成死机当机
Read more »

Java 泛型

泛型的好处

  1. 代码更健壮(编译器警告,不会出现ClassCastExceptiion);
  2. 代码更加简洁(不用强转);
  3. 代码更灵活,复用。

泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法

泛型类
1
2
3
4
5
6
7
8
9
10
11
public class Test<T>{ 
//key这个成员变量的类型为T,T的类型由外部指定
private T key;

public get(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
this.key = key;
}
public T set(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return key;
}
}
泛型接口
1
2
3
4
5
    //定义一个泛型接口
public interface Person<T> {
public T next();
}

当实现泛型接口的类,未传入泛型实参时
1
2
3
4
5
6
7

class Student<T> implements Person<T>{
@Override
public T next() {
return null;
}
}
当实现泛型接口的类,传入泛型实参时:
1
2
3
4
5
6
class Student implements Person<String>{
@Override
public T next() {
return null;
}
}

泛型方法

1
2
3
4
5
6
7
8
9
10
/**
* 泛型方法的基本介绍
* @param tClass 传入的泛型实参
* @return T 返回值为T类型
* 说明:
* 1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
*/
1
2
3
4
public <T> T get(Class<T> tClass){
T instance = tClass.newInstance();
return instance;
}
Read more »

垃圾回收算法

分代收集理论

当前商业虚拟机的垃圾收集器,大多遵循“分代收集”的理论来进行设计,这个理论大体上是这么描述的:

  1. 绝大部分的对象都是朝生夕死
  2. 熬过多次垃圾回收的对象就越难回收。
    根据以上两个理论,朝生夕死的对象放一个区域,难回收的对象放另外一个区域,这个就构成了新生代和老年代
Read more »

虚拟机中的对象

对象的分配

虚拟机遇到一条new指令时,首先检查是否被类加载器加载,如果没有,那必须先执行相应的类加载过程。
类加载就是把class加载到JVM的运行时数据区的过程

Read more »

Java Virtual Machine

JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。它能识别 .class后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作

翻译

Java 程序不一样,使用 javac 编译成 .class 文件之后,还需要使用 Java 命令去主动执行它,操作系统并不认识这些 .class 文件。所以JVM就是一个翻译

Read more »