黑马程序员技术交流社区

标题: 静态同步和非静态同步 [打印本页]

作者: 追逐    时间: 2014-3-18 15:04
标题: 静态同步和非静态同步
/*
如果同步函数被静态修饰后,使用的锁是什么呢?
通过验证,发现不在是this,因为静态方法中也不可以定义this。
1,静态同步
静态进内存时,内存中没有本类对象。但是一个有该类对于的字节码文件对象。
也就是类名.class    该对象的类型是Class

静态的同步方法,使用的锁是该方法所在类的字节码文件对象。

运用售票例子验证一下。
*/
class ShouPiao implements Runnable {
       
        boolean b = true;
        private static int piao = 1000; //定义票数
        public void run() {
                if(b) { //判断一下,如果b=true;就运行下面代码。如果等于false就不运行下面代码。
                        while(true) {
                                synchronized(ShouPiao.class) {
                                        if(piao > 0) {
                                                try {Thread.sleep(10);} catch(InterruptedException e) {}
                                                System.out.println("shou piao run--" + piao--);
                                        }
                                }
                        }
                } else {
                        while(true) {
                                show(); //调用同步函数
                        }
                }
        }
       
        public static synchronized void show() { //定义一个同步函数
                if(piao > 0) {
                        try {Thread.sleep(10);} catch(InterruptedException e) {}
                        System.out.println("show run...." + piao--);
                }
        }
       
}

class ShouPiaoTest1 {
        public static void main(String[] args) {
                ShouPiao sp = new ShouPiao();
                Thread t1 = new Thread(sp);
                Thread t2 = new Thread(sp); //创建线程
                t1.start(); //开启线程
                //线程开启后先睡眠一会在往下运行
                try {Thread.sleep(10);} catch(InterruptedException e) {}
                sp.b = false; //把变量b变为false,让线程可以执行第二个线程
                t2.start();
        }
}



2,非静态同步
/*

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

通过一个程序进行验证。

使用两个线程来买票
一个线程在同步代码块中,
一个线程在同步函数中。
都在执行买票动作。
*/

//定义类实现Runnable接口
class Test1 implements Runnable {
       
        boolean b = true;
        //Object obj = new Object();
        private int piao = 100;
        public void run() {
                if(b) {
                        while(true) {
                                synchronized(this) {
                                        if(piao > 0) {
                                                try {Thread.sleep(10);} catch(InterruptedException e) {}
                                                System.out.println("show run..." + piao--);
                                        }
                                }
                        }
                } else
                        while(true)
                                show();
        }
       
        public synchronized void show() {
                if(piao > 0) {
                        try {Thread.sleep(10);} catch(InterruptedException e) {}
                        System.out.println("run...show" + piao--);
                }
        }
       
}

class ShouPiaoTest {
        public static void main(String[] args) {
                //创建Runnable接口的子类对象
                Test1 t = new Test1();
                //创建四个线程,把Runnable接口的子类对象当成实参传递给线程的构造函数
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                t1.start();
                //让开启后先睡眠一会
                try {Thread.sleep(10);} catch(InterruptedException e) {}
                t.b = false;
                t2.start();
                //Thread t3 = new Thread(t);
                //Thread t4 = new Thread(t);
                //开启四个线程
               
                //t3.start();
                //t4.start();
        }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2