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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 迦南 中级黑马   /  2014-8-25 22:51  /  987 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

多线程
static Thread.currentThread(); 获取当前线程对象
this.getName();  获取线程名称
setName ; 设置线程名称

1.定义类实现Runnable接口
2.覆盖Runnbale接口中的run方法,将线程要运行的代码存放在该run方法中。
3.通过Thread类建立线程对象
4.将Runnbale接口的子类对象作为实际参数传递给Thread类的构造函数
为什么要将Runnable接口的子类对象传递给Thread的构造函数,因为,自定义的run方法所

属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确该

run方法所属的对象。
5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法


实现方式好处:避免了单继承的局限性。在定义线程时,建议使用实现方式。

两种方式区别:
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存放在接口的子类的run方法。

通过分析发现多线程的运行出现了安全问题,问题的原因:当多条语句在操作同一个线程

共享数据时,一个线程对多条语句只执行了一部分,还没执行完,另一个线程参与进来执

行,导致共享数据的错误。
解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以

参与执行
java对于多线程的安全问题提供了专业的解决方式。就是同步代码块。synchronized(对象

){需要被同步的代码}
对象如同锁。持有锁的线程可以在同步中执行,没有只有锁的线程即使获取了cpu的执行权

也进不去,因为没有锁。
火车上的卫生间--经典。
同步的前提:
1.必须要有两个或者两个以上的线程。
2.必须是多个线程使用同一个锁。必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
同步有两种变现形式
同步代码块
同步函数

同步函数用的是那一个锁呢?
函数需要被对象调用。那么函数都有一个所属对象引用,就是this.所以同步函数使用的锁

就是this.
如果同步函数被静态修饰后,使用的锁是什么呢?通过验证,发现不在是this.因为静态方

法中也不可以定义this。静态进内存时,内存中没有本来对象,但是一定有该类对应的字

节码文件对象。类名.class   该对象的类型是Class
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class
//懒汉式  延迟加载  如果多线程会出现安全问题 需要双重判断,  锁里面的对象是该类

所属的字节码文件
class Single{
        private static Single s = null;
        private Single(){}
        public static Single getInstance(){
                if(s==null){
                        synchronized(Single.class){
                                if(s==null)
                                s = new Single();
                        }
                }
                return s;
        }
}
class SingleDemo{
        public static void main(String[] args){
               
        }
}

死锁:
你持有一个锁,我持有一个锁,我到你那里运行,要拿你的锁,你要到我里面运行,要拿

我的锁,你也不给锁,我也不让锁,程序就挂了,产生死锁。
同步中嵌套同步,而锁却不同

线程间通信:
其实就是多个线程在操作同一个资源,但是操作的动作不同。

等待唤醒机制:
class Res{
        private String name;
        private String sex;
        private boolean flag = false;
        public synchronized void set(String name,String sex){
                if(flag){
                try(r.wait();}catch(Exception e){}
                this.name = name;
                this.sex = sex;
                flag = true;
                this.notify();
        }
        public synchronized void out(){
                if(!flag){
                        try(r.wait();}catch(Exception e){}
                        System.out.println(name+"....."+sex);
                        flag = false;
                        this.notify();
                }
        }
}
class Input implements Runnable{
        private Res r;
        Input(Res r){
                this.r = r;
        }
        public void run(){
                int x = 0;
                while(true){               
                        if(x==0){
                                r.set( "mike","man");
                                               
                        }else{
                                r.set( "丽丽","女女");
                                               
                        }
                        x = (x+1)%2;                                       
                }       
        }
}
class Output implements Runnable{
        private Res r;
        Output(Res r){
                this.r = r;
        }
        public void run(){
                while(true){
                        r.out();
                }
        }
}
class InputOutputDemo{
        public static void main(String[] args){
                Res r = new Res();
                new Thread(new Input(r)).start();
                new Thread(new Output(r)).start();
        }
}

notifyAll();
wait
notify
notifyAll
都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只

有同步才具有锁。为什么这些操作线程的方法要定义在Object类中呢?因为这些方法在操

作同步中线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的被等待线程

,可以被同一个锁上notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说等待和唤

醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object

类中。

private Lock lock = new ReentrantLock();
lock.lock();
condition.await();
condition.signal();
finally
lock.unlock();


stop方法已经过时
如何停止线程?
只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run方法结束,也就是线程结束。

4 个回复

倒序浏览
学习了,谢谢
回复 使用道具 举报

嗯,不用谢
回复 使用道具 举报
学习了,值得参考
回复 使用道具 举报
学习了!顶一个!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马