黑马程序员技术交流社区

标题: 多线程_2 以及单例设计模式_饿汉式 [打印本页]

作者: 2406035442    时间: 2014-10-15 22:23
标题: 多线程_2 以及单例设计模式_饿汉式
###四.线程之间的同步
* 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:39
楼主,能给一份文档吗?
作者: 2406035442    时间: 2014-10-15 22:50
没整理完。。。。
作者: a8851625    时间: 2014-10-16 01:27
这是在做整理学习笔记还是啥?
作者: め白衬衫    时间: 2014-10-16 11:33
好好记下了




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