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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 微笑的心情 中级黑马   /  2015-9-21 00:06  /  1110 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


多线程       
(1)就是应用程序有多条执行路径。
        进程:就是正在运行的程序。
        线程:就是进程的执行路径,执行单元。
       
       
(2).如何使用多线程(掌握)
        A:方式1 继承Thread类。
                        a:创建类继承Thread类
                        b:重写Thread类的run()方法。
                                run()方法里面才是封装线程的代码。
                        c:通过调用start()方法启动线程并调用run()方法。<<<start():第一,让线程启动。第二,自动调用run()方法。>>>
        代码体现:


public class MyThread extends Thread {
        @Override
        public void run() {
                for (int x = 0; x < 100; x++) {
                        System.out.println(getName()+"---hello" + x);
                }
        }
}

main(){

        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        my1.setName("用友");
        my2.setName("金蝶");

        my1.start();
        my2.start();
}

...................
        B:方式2        实现Runnable接口
                        a:创建一个类实现Runnable接口
                        b:重写run()方法
                        c:创建实现类对象,并把它作为参数传递给Thread类的构造方法,创建Thread对象
                        d:通过Thread的对象执行
        代码体现:

public class MyRunnable implements Runnable{

        @Override
        public void run(){
       
                for(int i=0;i<100;i++){
                        System.out.println(Thread.currentThread().class+"---"+i);
                }
        }

}
main(){

        MyRunnable my = new MyRunnable();

        Thread t1 = new Thread(my);
        Thread t2 = new Thread(my);

        t1.setName("乔峰");
        t2.setName("慕容复");

        t1.start();
        t2.start();
}

1.多线程        2.共有资源同步多线程        3.解决错误输出(加锁)        4.均匀输出
<<<既然有了继承Thread类的方式,为什么还要有实现Runnable接口的方式?
* A:避免的单继承的局限性
* B:实现接口的方式,只创建了一个资源对象,更好的实现了数据和操作的分离。
* 一般我们选择第二种方式。>>>
<<< 实现了Runnable接口的类没有start()方法,而我们启动线程必须调用start()方法。
又由于,start()方法只有Thread类有。所以,我们就考虑这个把该类转换成Thread类。>>>
...................
(3)线程的随机性原理
                多个程序其实是CPU的在做着高效切换执行的。

(4)线程的生命周期(面试题 画图自己补齐)
                新建
                就绪
                运行
                阻塞
                死亡

(5)线程安全问题
                A:卖票案例

                B:为什么有问题
                        a:有共享数据
                        b:共享数据被多条语句操作
                        c:在多线程环境中

(6)线程安全问题的解决方案:
                A:同步代码块
                        synchronized(锁对象)
                        {
                                被同步的代码
                        }
                B:同步方法
                        把synchronized加在方法上。

        一般推荐使用同步代码块。代码自己写一遍,然后粘贴到下面:

<<<同步代码块的锁对象是什么?
*                 同步代码块的锁是任意对象。
*
* 同步方法:就是把锁加在方法上
*                 格式:在方法上加synchronized关键字
*
*                 同步方法的锁对象是谁? this对象
*
* 静态方法的锁对象是谁呢?
*                 是当前类的字节码文件对象。
*                         类名.class        -        Class类型的对象
*
* 以后我们用同步代码块还是同步方法呢?
*                 被同步的内容越少越好,所以,一般使用同步代码块。               
*                 如果一个方法内部全部都被同步了,那么,可以考虑使用同步方法。>>>
public class TicketRunnable implements Runnable{

        private static int tickets = 100;
        private Object obj = new Object();
        private Demo d = new Demo();
       
        @Override
        public void run(){
                int x = 0;
                while(true){
                        if(x%2 == 0){        //加这条语句就是为了展示两种线程安全结局方案
                                synchronized(this){        //因为方法上的锁对象是this.
                                        if(tickets>0){
                                                Thread.sleep(100);        //这句必须try...catch...
                                                System.out.println(Thread.currentThread()+"---"+tickets--);
                                        }
                                }

                        }else{
                                check();//该方法用的是在方法上加synchronized;
                        }

                }       

        }

}

..............................
(7)线程间的通信问题
                学生类:
                设置学生属性的类:
                获取学生属性的类:
                测试类:


面试题:sleep和wait()的区别?
         wait():是Object类的方法,可以不用传递参数。释放锁对象。
         sleep():是Thread类的静态方法,需要传递参数。**不释放锁对象。


public class SetStudent2 implements Runnable {

public class GetStudent2 implements Runnable {

public class Student2 {

public synchronized void set(Student2 s){
                if (s.flag) {
                        try {
                                this.wait(100);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
                this.name = s.name;
                this.age = s.age;
               
//原因不在这,这里s从头到尾只有一个对象,所以用this和s是一样的。
//s.flag=true;        s.notify();
                this.flag = true;
                this.notify();
        }
        public synchronized void get(Student2 s){
                if (!this.flag) {
                        try {
                                this.wait(100);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
                System.out.println(s.name+"---"+s.age);
                this.flag = false;
                this.notify();
        }

}

(8)常见的方法
                优先级
                暂停线程
                加入线程
                守护线程

main方法本身就是一个线程。
*public final void setDaemon(boolean on):设置线程为守护线程,一旦前台(主线程),结束,守护线程就结束了。
DaemonDemo dd = new DaemonDemo();
Thread t1 = new Thread(dd);
t1.setDaemon(true);

public final void join():等待该线程终止。
* 一旦有join()线程,那么,当前线程必须等待,直到该线程结束。
JoinDemo pd = new JoinDemo();
Thread t1 = new Thread(pd);
t1.setName("林平之");
t1.join();                //需要处理异常

测试线程的优先级问题:
*                 线程默认优先级是5。范围是1-10。
* public final int getPriority():获取线程优先级
* public final void setPriority(int newPriority):更改线程的优先级。
* 注意:优先级可以在一定的程度上,让线程获较多的执行机会。
PriorityDemo pd = new PriorityDemo();
Thread t1 = new Thread(pd);
t1.setName("林平之");
t1.setPriority(10);

public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
Thread.yield();                //在线程run()方法里使用。


(9)面试题:
                sleep()和wait()的区别?
                启动线程到底调用的是哪个方法?

                run()和start()的区别?
                同步的原理,以及有几种实现方式?


多线程记住这几个代码就好:
**4个窗口买100张票 数据无误
**学生类设置、获取信息交替


点评

还不错  发表于 2015-9-21 09:07

评分

参与人数 3黑马币 +14 收起 理由
橘子你个哈密瓜 + 6 赞一个!
赖丽霖老师 + 4
aaaaaaaaaa + 4 赞一个!

查看全部评分

5 个回复

倒序浏览
橘子你个哈密瓜 来自手机 中级黑马 2015-9-21 00:19:22
沙发
微笑的心情 发表于 2015-9-21 00:06
多线程       
(1)就是应用程序有多条执行路径。
        进程:就是正在运行的程序。

写的挺详细的额
回复 使用道具 举报
总结的挺全面的,学习了
回复 使用道具 举报
先留着,用得上
回复 使用道具 举报
总结的挺全面的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马