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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 2406035442 中级黑马   /  2014-10-15 22:23  /  1787 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

###四.线程之间的同步
* 1.什么情况下需要同步
        * 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
        * 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
* 2.同步代码块
        * 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
        * 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的

                        class Printer {
                                Demo d = new Demo();
                                public static void print1() {
                                        synchronized(d){                                //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
                                                System.out.print("黑");
                                                System.out.print("马");
                                                System.out.print("程");
                                                System.out.print("序");
                                                System.out.print("员");
                                                System.out.print("\r\n");
                                        }
                                }
       
                                public static void print2() {       
                                        synchronized(d){       
                                                System.out.print("传");
                                                System.out.print("智");
                                                System.out.print("播");
                                                System.out.print("客");
                                                System.out.print("\r\n");
                                        }
                                }
                        }
* 3.同步方法
        * 使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的
       
                        class Printer {
                                public static void print1() {
                                        synchronized(Printer.class){                                //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
                                                System.out.print("黑");
                                                System.out.print("马");
                                                System.out.print("程");
                                                System.out.print("序");
                                                System.out.print("员");
                                                System.out.print("\r\n");
                                        }
                                }
                                /*
                                 * 非静态同步函数的锁是:this
                                 * 静态的同步函数的锁是:字节码对象
                                 */
                                public static synchronized void print2() {       
                                        System.out.print("传");
                                        System.out.print("智");
                                        System.out.print("播");
                                        System.out.print("客");
                                        System.out.print("\r\n");
                                }
                        }
* 4.线程安全问题
        * 多线程并发操作同一数据时, 就有可能出现线程安全问题
        * 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
                       
                        public class Demo2_Synchronized {

                                /**
                                 * @param args
                                 * 需求:铁路售票,一共100张,通过四个窗口卖完.
                                 */
                                public static void main(String[] args) {
                                        TicketsSeller t1 = new TicketsSeller();
                                        TicketsSeller t2 = new TicketsSeller();
                                        TicketsSeller t3 = new TicketsSeller();
                                        TicketsSeller t4 = new TicketsSeller();
                                       
                                        t1.setName("窗口1");
                                        t2.setName("窗口2");
                                        t3.setName("窗口3");
                                        t4.setName("窗口4");
                                        t1.start();
                                        t2.start();
                                        t3.start();
                                        t4.start();
                                }
                       
                        }
                       
                        class TicketsSeller extends Thread {
                                private static int tickets = 100;
                                static Object obj = new Object();
                                public TicketsSeller() {
                                        super();
                                       
                                }
                                public TicketsSeller(String name) {
                                        super(name);
                                }
                                public void run() {
                                        while(true) {
                                                synchronized(obj) {
                                                        if(tickets <= 0)
                                                                break;
                                                        try {
                                                                Thread.sleep(10);//线程1睡,线程2睡,线程3睡,线程4睡
                                                        } catch (InterruptedException e) {
                                                               
                                                                e.printStackTrace();
                                                        }
                                                        System.out.println(getName() + "...这是第" + tickets-- + "号票");
                                                }
                                        }
                                }
                        }
* 5.死锁问题
        * 多线程同步的时候, 如果同步代码嵌套, 使用相同锁, 就有可能出现死锁
        * 尽量不要嵌套使用
               
                        private static String s1 = "筷子左";
                        private static String s2 = "筷子右";
                        public static void main(String[] args) {
                                new Thread() {
                                        public void run() {
                                                while(true) {
                                                        synchronized(s1) {
                                                                System.out.println(getName() + "...拿到" + s1 + "等待" + s2);
                                                                synchronized(s2) {
                                                                        System.out.println(getName() + "...拿到" + s2 + "开吃");
                                                                }
                                                        }
                                                }
                                        }
                                }.start();
                               
                                new Thread() {
                                        public void run() {
                                                while(true) {
                                                        synchronized(s2) {
                                                                System.out.println(getName() + "...拿到" + s2 + "等待" + s1);
                                                                synchronized(s1) {
                                                                        System.out.println(getName() + "...拿到" + s1 + "开吃");
                                                                }
                                                        }
                                                }
                                        }
                                }.start();
                        }
###一.线程的方法
* 1.yield让出cpu
* 2.setPriority()设置线程的优先级

###二.单例设计模式
* 单例设计模式:保证类在内存中只有一个对象。

* 如何保证类在内存中只有一个对象呢?
        * (1)控制类的创建,不让其他类来创建本类的对象。private
        * (2)在本类中定义一个本类的对象。Singleton s;
        * (3)提供公共的访问方式。  public static Singleton getInstance(){return s}

* 单例写法两种:
        * (1)饿汉式 开发用这种方式。
        *
                        //饿汉式
                        class Singleton {
                                //1,私有构造函数
                                private Singleton(){}
                                //2,创建本类对象
                                private static Singleton s = new Singleton();
                                //3,对外提供公共的访问方法
                                public static Singleton getInstance() {
                                        return s;
                                }
                               
                                public static void print() {
                                        System.out.println("11111111111");
                                }
                        }

点评

资源多的话,可以上传压缩包。这样大家看起来也比较方便  发表于 2014-10-15 22:24

5 个回复

倒序浏览
楼主,能给一份文档吗?
回复 使用道具 举报
没整理完。。。。
回复 使用道具 举报
这是在做整理学习笔记还是啥?
回复 使用道具 举报
好好记下了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马