A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

沉醉

中级黑马

  • 黑马币:45

  • 帖子:25

  • 精华:0

Course(进程)
什么是进程?
        进程就是在某种程度上相互隔离的、独立运行的程序
什么是多进程?
        就是让系统看起来像是同时运行多个程序

注意:对于一个CPU而言,在某个时间点上只能执行一个程序,多进程只是在多个程序间进行不断跳跃,执行

Thread(线程)
什么是线程?
        线程是指程序中的某个任务
什么是多线程?
        多线程是指在能够同时运行多个线程的程序就叫做多线程
       
多进程和多线程的区别?
        对于进程来说,每个进程都有自己的一组完整的变量,而线程则是共享相同数据的
       
       
线程的创建方式
方式一:通过继承Thread类,创建线程
方式二:通过实现Runnable接口,创建线程

两种创建方式的比较:
(1)使用Runnable
        使用Runnable接口,可以将CPU、代码和数据分开,形成清晰的模型
        还可以从其它地方继承类
        保持程序风格的一致性
(2)直接继承Thread类
        不能再从其它类继承
        编写简单,可以直接操纵线程,无需使用Thread.currentThread().
       
Thread类
特性:实现Runnable接口,程序中的某个线程
方法:
构造方法:
        Thread():创建一个默认名称的Thread
        Thread(String name):创建一个指定名称的Thread
        Thread(Runnable target)
        Thread(Runnable target,String name)
        Thread(ThreadGroup group,String name)
        Thread(ThreadGroup group,Runnable target)
        Thread(ThreadGroup group,Runnable target,String name):创建一个指定名称,指定调用run方法的target和该线程属于group的Thread对象
        Thread(ThreadGroup group,Runnable target,String name,long stackSize)
普通方法:
        static Thread currentThread():返回对当前正在运行的线程的引用
        int getPriority()[praɪ'ɒrɪtɪ]:返回当前线程的优先级
        void setPriority(int newPriority()):设置线程的优先级
        static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
        void start():使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
        static void yield():暂停当前线程,并且执行其它线程
        long getId():返回该线程的标示符
        String getName():返回该线程的名称
        void setName(String name):设置线程的名称
        Thread.State getState():返回该线程的状态
        ThreadGroup getThreadGroup():返回该线程所处的线程组
        void interrupt():中断线程
        bolean interrupted():判断该线程是否已经终止
        boolean isAlive():判断该线程是否还活着
        boolean isDaemon()['diːmən]:判断该线程是否为守护线程
        void setDaemon():将该线程标记为守护线程活着是用户线程
        void join():等待线程的结束
        void join(long millis):在指定时间内等待线程的结束
        void run():如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回
               
后台线程(守护线程)
什么是后台线程?
在后台运行的,为其它的线程提供服务,这种线程被称为后台线程(Daemon Thread)
作用:一般用于任务结束时的善后处理
特点:优先级一般比其它线程低

注意:
和后台线程相比较,一般线程称为“用户线程”
如果一个应用中只有后台线程在运行,JVM将退出该应用程序
Thread State(线程状态)       

五种状态:New(新建)、Runnable(可运行)、Running(运行)、Blocked(阻塞)、Dead(死亡)
关系图:     
New --> 通过调用start() --> Runnable <--> 线程调度 --> Running -->run()完毕 -->Dead               
Running --> 发生某些阻塞时间 --> Blocked --> 通过解除阻塞 --> Runnable
               
线程详解:
(1)当使用了new来新建一个线程时,它处于New状态,这个时候,线程并未进行任何操作
(2)然后,调用线程start()方法,来向线程调度程序(通常是JVM或操作系统)注册一个线程,这个时候,这个线程准备就绪,等待CPU时间
(3)线程调度程序根据调度策略来调度不同的线程,调用线程的run()方法给已经注册的各个线程以执行的机会,被调度的线程
进入Running状态。当线程的run()方法执行完毕,线程将被抛弃,进入Dead状态,此时,不能使用restart()方法重新开始已死掉的线程,但
可以使用处于死亡状态的线程方法
(4)如果线程在Running()状态中因为IO阻塞、等待键盘录入,调用了线程的sleep()方法,调用了对象的wait()方法等操作,则线程将进入Blocked(阻塞)状态,
直到这些阻塞原因被解除,解除后将进入Runnable状态,重新等待线程调度程序调度,注意的是,被阻塞的线程,解阻塞后不会直接进入Running状态
               
线程什么时候结束?
(1)当线程的run()方法执行到结尾之后
(2)当线程抛出一个未捕获的异常或者错误之后
(3)当另一个线程调用一个Deprecated的stop()方法(不建议使用)

线程的控制

1)中断线程
static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
static void yield():暂停当前线程,并且执行其它线程
两者的区别:
        相同点:sleep()和yield()在调用后都将会让出CPU的控制权
        不同点:sleep()在指定的睡眠时间内,一定不会获得运行的机会,直到它睡眠的时间结束
            而yield()方法在让出控制权后。还有可能马上被系统的调度机制选中来运行,这样就不能达到让出控制权的目的
                            
注意:当一个线程在执行很长的循环时,应该适当的调用sleep()和yield()方法,确保其它线程可以得到运行的机会,否则就是一个利己线程。
2)线程Join方法的使用
public class JoinThreadTest {       
        static int[] a = new int[50];       
        public static void main(String args[]){
                JoinThread jt = new JoinThread();
                Thread thread = new Thread(jt);
                thread.setName("chenzui");
                thread.start();
                try{
                        thread.join();
                }catch(InterruptedException e){
                        e.printStackTrace();
                }
                for (int i = 0; i < a.length; i++) {
                        System.out.println(thread.getName()+":"+a[i]);
                }
        }
        static class JoinThread implements Runnable{
                public void run(){
                        for (int i = 0; i < 50; i++) {
                                System.out.println("i:"+(i-50));
                                a[i] = i-50;
                        }
                }
        }
}
Multi-Thread(多线程)
“多线程”描述的是,在主线程中有多个线程在运行,
一般指:
多个线程来自同一个Runnable实例
多个线程使用同样的数据和代码

多线程中的共享数据问题
原因:多线程中,数据共享,因为不是同步的因素,会导致,当某个线程在对某个数据进行操作的过程中,还没操作完成,
        就被另一个线程打断,使得第一个线程修改的数据,没有被第二个线程获取到,结果是两个线程的结果不一致的问题
       
解决方法:使用synchronized(线程锁)       
synchronized(线程锁、互斥锁、对象锁):线程锁锁定的是当前调用的对象

synchronized的使用方式:
        (1)放在方法前面,这样调用该方法的线程将获得当前对象上的锁
        (2)放在代码块前面,用于修饰对象引用,两种方式:
                用于修饰当前对象的引用————synchronized(this){.....}
                        或synchronized{.......}代码块中的代码将获得当前对象引用的锁
                用于修饰指定的对象————synchronized(Object obj){}:代码块中的代码将获得指定
                        对象引用的锁
                       
注意:synchronized也可以用来修饰类,被修饰的类表示里面的方法都是synchronized的
        一个类中只有某个或多个方法被synchronized修饰,当某个线程调用该类中被锁定的方法时,其它
        线程可以调用该类中的无锁方法

线程归还锁的时机:
        当线程执行到synchronized块结束的时候,释放对象锁
        当在synchronized中遇到return、break或Exception时,将自动释放对象锁
        当一个线程调用wait()方法时,它放弃拥有的对象锁并进入等待队列
       
使用synchronized遇到死锁的原理:
        一个程序中,锁定了两个或两个对象,当某个线程获取了第一个对象上的锁,在等待第二个对象的锁时,此时
                有另一线程取得第二个对象上的锁,同时也在等待第一个对象上的锁时,就出现了大家都在等待的现象,
                这就是死锁。
解决死锁的方法:保证在获取多个锁的同时,每个线程都是以相同的顺序获取锁的。
       
线程间的通信:
        原理:使用Object我对象中的wait()、notify()、notifyAll()方法,通过某个条件将调用者释放锁
        并且等待,其它线程获得锁运行,通过调用notify或notifyAll唤醒等待在该对象的上的所有线程,从而实现
        线程间的通信原理
               
        wait:是使调用某个对象的线程,在调用的对象上进行等待
        notify和notifyAll:是指唤醒在调用的对象上等待的线程,notify是唤醒一个(具体唤醒哪个,由系统决定),
                notifyAll唤醒的是所有线程
        wait和sleep的区别:wait会使线程释放占用的对象锁,sleep不会使线程释放所占有的锁
                               
        旋锁:
                原理:在线程通信间,当使用判断条件控制是否等待时,需要使用while循环进行判断,叫做“旋锁”
                目的:是为了解决两个或两个以上线程同时苏醒后,后面的线程能够再次判断等待条件,保证程序的安全性

评分

参与人数 1黑马币 +4 收起 理由
Hakka_LGM + 4 好详细呀。给力!已收藏

查看全部评分

8 个回复

正序浏览
黄蒙 中级黑马 2015-8-12 08:48:51
9#
刚学到线程。。边看边学//
回复 使用道具 举报
哇,学习了
回复 使用道具 举报
陈绍坚 来自手机 中级黑马 2015-8-12 00:53:24
7#
不错哦。
回复 使用道具 举报
总结得挺详细,还叫肤浅?差不多把API的多线程都搬来了·~~~
回复 使用道具 举报
哥们儿,给力!
回复 使用道具 举报
回复 使用道具 举报
13798223575 来自手机 中级黑马 2015-8-12 00:09:58
藤椅
很厉害的样子
回复 使用道具 举报
首个沙发,自己顶上
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马