前言
本人某工科背景院校小硕一枚,2014年4月毕业,5月正式开始了自己正式的劳动者生涯。在一家技术不是那么牛逼(更客观的说是不太适合技术成长)的大公司搞起了Android。在此之前从来没有接触过Java,跟java的唯一缘分就是本科毕业的时候班上一死党离校前给我留了本Java基础教程,说是研究生说不定会用到,可惜2年半的研究生那本书一直躺在那里,直到入职真正搞起Android,它一直没有被翻起。就是这样跟java几乎没有瓜葛的我,鬼使神差走了GS运过了n轮面试拿到Android的offer。入职的当天才被告知被分到了framework team。对于Androidframework直到现在我还没有深刻的认识。
近一年来,被mentor带着会使用一些常用的干活的工具后,便开始了自己的神游。整个team绝大部分时间、绝大部分人都在解bug,对于我这职场新手、java新手、Android新手来说,通过解framework 的bug来实现技术积累是个极度痛苦的过程。技术的积累和学习主要还是靠自己。在网络上遍搜各种Android学习路线、经验,像个苍蝇一样撞来撞去。直到看了singwhatiwanna大神的一篇文章http://blog.csdn.net/singwhatiwanna/article/details/42343847,其中大神给出了几种重要的技术学习和积累的方法,写技术博客和参加开源github就在其中,github已在前几天开启。今天正式开启自己的技术博客之旅,期待能像大神那样,通过这种方式尽快提高自己,顺便也希望自己所写所想所历能给一些刚入门的同行者们有些帮助吧。
我这人有一毛病,喜欢抠细节的东西,看到一段代码喜欢一行一行看明白,这种习惯其实很不好,效率极其低下,而且对于技术积累没太大帮助。就像网上很多大神说过,学习一门技术或者一个具体的机制,应该是自上而下的学习,先从宏观上对整体有个把握,再慢慢深入下去研究细节;如果开始就直接一猛子扎下去,很容易迷失自己,更极端容易摧残自己的自信心。我已经吃了很多苦头,但习惯改的还是不彻底,经常容易掉进去,哎,应试教育坑人啊。虽然说过分关注细节不好,但是,有个扎实的基础对于后续的技术学习绝对是有好处的。本人记忆力不好,学过很多很多东西,每每自我感觉理解的很透彻,但是几天不用、不看,再见面又一副陌生人的面孔;希望博客能帮我克服这个问题,记录自己学习积累的脚步。
正式开始自己第一篇博客的技术内容。写本篇博客前,刚看了mars大神的java4android教学视频的线程机制部分,趁热打铁,就拿java中的线程机制开刀了。本篇博客内容主要记录自己的学习思路,会跟教学视频中有很大雷同性,请勿拍砖。谢谢哈
1. 多进程和多线程的概念
1.1 多进程:多进程就是在操作系统中能(同时)运行多个任务(程序、软件),这里的“同时”只是用户感官上的同时,实际上,这种同时是CPU在短时间内快速、轮流执行多个任务实现的。对于初学者而言,可以将一个进程近似理解为一个普通的应用程序,像音乐播放器(酷狗)、文本编辑器(windows里的写字板)等。
1.2多线程:多线程就是在同一个进程(任务、应用程序、软件)中,有多个顺序流(同时)执行(即同时执行一大段代码中的多处代码)。此处的同时跟多进程的同时意思差不多,是感官上的错觉。
2.线程的生命周期
3 创建线程的方法
3.1 继承Thread类
定义一个线程类,它继承类Thread并重写其中的run()方法,方法run()称为线程体
由于Java只支持单继承,用这种方法定义的类不能再继承其他类。
示例代码:
文件1:FirstThread.java
classFirstThread extends Thread{
public void run(){
for(int i = 0; i < 100; i ++){
System.out.println("FirstThread->"+i);
}
}
}
文件2:Test.java
classTest{
public static void main(String args[]){
//生成线程类的对象,进入new状态
FirstThread ft = newFirstThread();
//启动线程,进入就绪runnable状态
ft.start();
//ft.run();千万不能这么写,这个是在主线程中直接调用,没有另开新线程,而是顺序执行。
for(int i = 0; i < 100; i++){
System.out.println("main--> "+ i);
}
}
}
3.2 使用Runnable接口
文件1:RunnableImpl.java
classRunnableImpl implements Runnable{
voidrun(){
for(int i = 0; i < 100; i ++){
System.out.println("RunnableImpl->"+i);
if(i == 50){
try{
Thread.sleep(2000);
}
catch (Exception e){
System.out.println(e);
}
}
}
}
}
文件2:Test.java
classTest{
public static void main(String args[]){
//生成一个Runnable接口实现类的对象
RunnableImpl ri = new RunnableImpl();
//生成一个Thread对象,并将Runnable接口实现类的对象作为参数传给Thread对象
Thread t =new Thread(ri);
//线程最大优先级为10,最先为1,默认为5。优先级越高,抢到cpu的概率越大,不绝对先抢到
t.setPriority(Thread.MAX_PRIORITY);
//通知Thread对象,执行start方法
t.start();
System.out.println(t.getPriority());
}
}
4 线程的简单控制方法
4.1 中断线程
----Thread.sleep() //退出running状态进入Blocedk状态持续X毫秒,然后进入Runnable状态
----Thread.yield() //退出running状态直接进入Runnable状态,开抢Cpu
4.2 设置线程的优先级
----getPriority()
----setPriority()
5 多线程安全---线程同步(synchronized关键字的使用)
文件1:Thread.java
classMyThread implements Runnable{
int i = 100;
public void run(){
synchronized(this){
while(true){
//Thread.currentThread()//返回当前线程对象(对象的引用)
System.out.println(Thread.currentThread().getName()+i);
i --;
Thread.yield();//让出CPU ,让当前线程重新参与竞争
if(i < 0){
break;
}
}
}
}
}
文件2:Test.java
classTest{
public static void main(String args[]){
MyThread myThread = newMyThread();
// 生成两个Thread对象,但是这两个Thread对象共用同一个线程体
Thread t1 = new Thread(myThread);
Thread t2 = new Thread(myThread);
//每一个线程都有名字,可以通过Thread对象的setName()方法设置
//线程名字,也可以使用getName方法获取线程的名字
t1.setName("线程a"); //等效于Thread t1 = new Thread(myThread,"线程a");
t2.setName("线程b");
//分别启动这两个线程
t1.start();
t2.start();
}
}
关于synchronized关键字的使用,网上有个帖子,个人觉得总结的很好,浅显易懂,考虑了各种使用情况,链接如下:
http://www.cnblogs.com/mengdd/archive/2013/02/16/2913806.html
不再详述