JasonWang's Blog

JasonWang's Blog

Java并发编程之同步

在单一线程执行的情况下,并不用考虑任何数据一致性与同步等问题,但到了多个线程执行的情况下,共享数据的同步就显得至关重要了。比如有一个银行账户的操作问题(例子来自Wikipedia),现在有两个线程A与B共享一个账户变量balance,这个提款的操作有两个部分,首先需要判定提款数目是否小于当前账户存款,记为s1;如果该条件满足,则从账户中提取资金,记为s2。假定开始时账户balance=600,现在A调用withdraw(200),B调用withdraw(500),如果两个线程A与B调用时,s1都发生在s2之前,则两个线程都可以进入判定条件,提取相应的资金,而实际的存款是小于两个线程需要提取的资金的。

1
2
3
4
5
6
7
8
9
10
11
12
13

bool withdraw(int withdrawal)
{

if (balance >= withdrawal) // --> s1
{

balance -= withdrawal; // --> s2
return true;
}
return false;
}

这种线程之间共享资源的一致性同步问题在并发编程中十分常见,通常被称为Data Race。根据官网上的定义(what is data race),Data Race出现是由以下原因导致:

  • 多个线程同时访问共享内存;
  • 至少有一个线程写该共享内存区域;
  • 线程访问共享内存并没有利用锁进行同步;
Java并发编程之线程

线程作为操作系统的最小调度单位。一个进程里可以有多个线程,这些线程有各自的程序计数器、堆栈空间和局部变量,而且可以共享进程的内存空间,因而在上下文切换时时间更短,效率更高,也常被成为轻量级进程(Light Weight Process)。接下来,将从三个方面来介绍Java线程类Thread的具体用法:

  • 线程构造与初始化;
  • 线程状态切换;
  • 线程变量ThreadLocal的使用

Thread: https://en.wikipedia.org/wiki/Thread_(computing)

单例模式在Java中的应用

单例模式(Singleton Pattern)用于确保系统中某个类只有一个实例存在,即该类被创建初始化一次后,之后都不会再被创建。这里就来看下单例模式在Java中常见的几种实现方式:

  • 双重检查锁
  • 类初始化
  • enum类型实现
Picasso从使用到原理详解

Picasso是SquareUp公司开源的专门为Android平台量身制作的图片加载库。通过Picasso,用户可以方便的将图片加载到特定的ImageView中,而不用关心图片是在一个文件夹里,还是在一个服务器上。那么,Picasso是如何何实现图片的快速加载了?

  • 利用两级缓存机制对图片进行缓存: 加载一个图片时,首先从内存中查看是否存在;如果不存在,则查看外部存储是否有该图片。这时,如果还没有找到,则通过网络端下载图片;
  • 利用OkHttp库进行图片下载,下载后保存到缓存,下次请求时无需从网络端下载;如果出现网络错误,会自动重试下载;
TCP/IP网络协议入门

互联网是由一个个电脑节点组成的网络,那么两个节点之间是如何进行数据通信的了?先来看一看一个最简单的通信模型:发送者通过一个媒介想一个接收者发送消息,同时接收者也可以向发送者发送消息。

这种通信模型与平时生活中的日常会话很是相似。A想与B交流,首先A与B要讲同样的方言,如果一个人讲湖南方言,而一个人讲粤语,则沟通无法进行, 除非请一个懂两种方言的翻译或者沟通双发统一使用某一种语言。抽象的来看,通信一般涉及到如下几个要素:

  • 两个需要通信的节点(地址);
  • 通信的数据交换协议(协议);
  • 节点之间的物理连接(媒介);
关于Maven

什么是Maven

Maven是一个自动化构建工具,最开始只适用于Java项目,后来逐渐支持C#,Ruby等项目的构建。Maven使用XML格式文件来描述一个项目的依赖,被称为Project Object Model(POM)。一个pom.xml描述了一个项目所有的配置,包括项目信息,项目所依赖的包等等。

Maven可以从一个或者多个代码仓库里(Maven 2 Central Repository)动态下载Java库文件以及插件,并将其保存到本地的仓库里(缓存),从而实现依赖的更新。

自动构建:https://en.wikipedia.org/wiki/Build_automation

《Effective Java》摘记

第一遍看完感觉没有学到什么,又看了一遍,然后自己找了些实例对比着理解了书上的要点,算是对Java编程有了更多的认识。以下是 《Effective Java 2nd edition》的摘记。

Consider static factory methods instead of constructors

相比构造函数,静态工厂方法有哪些优点了?首先,静态工厂方法有自己的名字,这可以增强程序的可读性;其次,静态工厂方法每次调用时,不用创建新的对象实例;第三,静态工厂方法可以返回其返回类型的任何子类型对象。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{

public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

....
//根据boolean值返回相应的Boolean对象
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}

}

Android Phone进程启动过程分析

之前解决一个开机搜网慢的问题时,发现由于Phone进程起来以后才会主动连接RILD,因而在一定程度上Phone进程启动的时间会影响网络状态注册的快慢。适当的将Phone进程提前,可以将网络注册时间提前一点,让状态栏中信号显示的时间提前。那么,Android中作为系统的核心进程之一,Phone进程是如何启动的了?

本文参考代码为Android NN7.0, RIL运行机制请参考: Android RIL概述

Android Launcher工作原理

Android系统启动完成后,第一个启动的Activity就是主界面应用程序Launcher,相当于电脑的桌面。Launcher界面可以看到系统中安装的所有APP,点击APP即可启动该APP应用了。那么,Launcher到底是如何启动的以及如何自定义自己的Launcher了?这篇文章我们就来讲讲这两个问题。

avatar
JasonWang
生命短暂,莫空手而归