现在的位置: 首页 > 综合 > 正文

Java从菜鸟到精通(10)

2013年08月27日 ⁄ 综合 ⁄ 共 3962字 ⁄ 字号 评论关闭

单例设计模式。
1、饿汉式

/*
  class  Single{
    //写上final更严谨,s永远指向Single()
    private static [final] Single s=new

Single();
    private Single(){}
    public static Single getInstance(){
        return s;
    }
}

*/
***********************
************************
************************
2、懒汉式*****面试****
//在多线程访问时,会产生安全隐患
1.懒汉式与饿汉式有什么不同?
懒汉式的特点:用于实例的延时加载
2.实例的延时加载有没有问题?
有。如果多线程访问时,会出现安全问题。
3.怎么解决?
可以使用同步来解决。而加同步的方式,用同步函

数或者同步代码块都行,但是稍微有些低效。
4.怎么解决低效?
用双重判断的形式来解决低效问题。
5.加同步的时候,使用的锁是哪一个?
该类所属的字节码面向对象。
6.笔试题:写出一个延时加载的单例设计模式实例

。(如下)
class Single{
    private static Single s=null;
    private Single(){}
    public static [synchronized] Single

getInstance(){
    if(s==null){
    synchronized(Single.class){
     if(s==null){
        //--> Thread A
        s=new Single();
    }    
    }
}
     return s;
    }
}

死锁。
就是说,A持有一个锁,B也持有一个锁,A要到B里

面去运行,要拿B的锁,而B要到A里面运行,必须

拿A的锁,这样会出现,A不放自己的锁,去B里面

运行,B也不放自己的锁,到A里面去运行,谁都不

放,就导致死锁。这样出现的情况是:程序就不会

运行了。
最可能出现死锁的是:同步中嵌套同步,而锁不同


************面试******
请写一个死锁的程序?
死锁例子:
class Test implements Runnable
{
    private boolean flag;
    Test(boolean flag){
        this.flag=flag;
    }       
    public void run(){
    
        if(flag){
while(true){
            synchronized

(MyLock.locka){
            syso("if TestA")
            synchronized

(MyLock.lockb){
            syso("else testB");
            }
            }
}
        }else {
        while(true){
            synchronized

(MyLock.lockb){
            syso("if TestB");
            synchronized

(MyLock.locka){
            syso("else testA");
            }
            }
        }
    }
}
}

class MyLock
{
    static Object locka=new Object();
    static Object lockb=new Object();
    
}

class DeadLockTest{

    public static void main(String []

args){
Thread t1=new Thread(new Test(true));
Thread t2=new Thread(new Test(flase));
t1.start();
t2.start();
    }
}

多线程间的通信
例程
---input-->资源---output--->
思考1:
wait(),notify(),notifyAll(),用来操作线程为什

么定义在Object类中?
1、这些方法存在与同步中。
2、使用这些方法时必须要标识所属的同步锁。
3、锁可以是任意对象,所以任意对象调用的方法

一定定义Object类中。

思考2:
wait(),sleep()有什么区别?
wait():释放资源,释放锁。
sleep():释放资源,不释放锁。

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

动作不同。

class Res{
    String name;
    String sex;
}
class Input implements Runnable
{    
    private Res r;
    //Object obj=new Object();
    Input(Res r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true)
        {
//资源是唯一的所以就传r
    synchronized(r){
        if(x==0){
        r.name="mike";
        r.sex="man"
        }else{
        r.name="XX";
        r.sex="X"
        }
        x=(x+1)%2;
        }
}
    }
}
class Output  implements Runnable
{
    private Res r;
    //Object obj=new Object();
    Onput(Res r){
        this.r=r;
    }
    public void run(){
        while(true)
        {
    synchronized(r){
        syso(r.name+r.sex);
    }
        }
    }

}

class InputOutputDemo
{
    public static void main(String []

args)
    {
    Res r=new Res();
    
    Input in=new Input(r);
    Output out=new Output(r);
    
    Thread t1=new Thread(in);
    Thread t2=new Thread(out);
    
    t1.start();
    t2.start();
    }
}

****线程间通信--------等待唤醒机制
例题:
class Res{
    String name;
    String sex;
    boolean flag=false;
}
class Input implements Runnable
{    
    private Res r;
    //Object obj=new Object();
    Input(Res r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true)
        {
//资源是唯一的所以就传r
    synchronized(r){
    if(r.flag)
    try{r.wait();}catch(){}//放弃了执行

资格
    //放在在线程池里
        if(x==0){
        r.name="mike";
        r.sex="man"
        }else{
        r.name="XX";
        r.sex="X"
        }
        x=(x+1)%2;
    r.flag=true;
    r.notify();
//唤醒线程池里线程,通常唤醒第一个被唤醒的
        }
}
    }
}
class Output  implements Runnable
{
    private Res r;
    //Object obj=new Object();
    Onput(Res r){
        this.r=r;
    }
    public void run(){
        while(true)
        {
    synchronized(r){
        if(!r.flay)
        try{r.wait();}catch(){}
        syso(r.name+r.sex);
        r.flag=false;
        r.notify();
    }
        }
    }

}

class InputOutputDemo
{
    public static void main(String []

args)
    {
    Res r=new Res();
    
    Input in=new Input(r);
    Output out=new Output(r);
    
    Thread t1=new Thread(in);
    Thread t2=new Thread(out);
    
    t1.start();
    t2.start();
    }
}
------------------------------
wait():
notify():
notifyAll():
都使用在同步中,因为要对持有监视器(锁)的线

程操作。
所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义在Object类中呢


因为这些方法在操作同步中线程时,都必须要标识

他们所操作线程只有的锁,只有同一个锁上的被等

待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。
而锁可以是任意对象,所以可以被任意对象调用的

方法定义在Object类中。

抱歉!评论已关闭.