精华内容
下载资源
问答
  • 同步代码块解决继承Thread类的线程安全问题 与用同步代码块解决实现Runnable接口创建线程的安全问题的 不同之处在于:①不能使用this来充当同步监视器 ②要在创建对象的前面加上static,以保证唯一性 Eg:不能写成 ...

    同步代码块解决继承Thread类的线程安全问题

    与用同步代码块解决实现Runnable接口创建线程的安全问题的
    不同之处在于:①不能使用this来充当同步监视器
    ②要在创建对象的前面加上static,以保证唯一性
    Eg:不能写成 Object obj = new Object();
    应写成 static Object obj = new Object();
    即要他们共用一把“锁”

    package com.xianchengtest.bean;
    
    public class Test {
        public static void main(String[] args) {
            Thread6 t1 = new Thread6();
            Thread6 t2 = new Thread6();
            Thread6 t3 = new Thread6();
            t1.setName("窗口一");
            t2.setName("窗口二");
            t3.setName("窗口三");
            t1.start();
            t2.start();
            t3.start();
        }
    }
    class Thread6 extends Thread {
        private static int ticket = 100;
        private static final Object obj = new Object();
        public void run() {
            while (true) {
                synchronized (obj) {   
                    if (ticket > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(getName() + "卖的票号为:" + ticket);
                        ticket--;
                    } else {
                        break;
                    }
                }
            }
        }
    }
    
    
    展开全文
  • 转载于:https://www.cnblogs.com/classmethond/p/10099817.html

     

    转载于:https://www.cnblogs.com/classmethond/p/10099817.html

    展开全文
  • 好记性不如赖笔头……...继承了Thread类的类,在创建线程时,如果使用了同步,那么它默认对象默认为 类名.class,原因在于继承Thread的类在创建线程时,每创建一个线程创建了一个新的对象,要保证它的是固定的

    好记性不如赖笔头…………

    线程的生命周期:

    1.新建:使用new创建对象,
    2.准备就绪:调用了start()方法,但还没有抢占到CPU资源
    3.运行:调用了start()方法并抢占到了cpu资源,开始执行
    4.阻塞:调用 sleep()/wait()方法,使线程让出CPU资源并进入休眠状态,可调用notity()方法使线程进入到准备就绪状态
    5.销毁:run方法执行结束或调用 stop()方法后,线程已经不在使用,成为了垃圾线程,将GC回收

    两种创建线程的方法在使用同步锁的区别

    1. 实现了Runnable接口的类创建线程:
      因在创建多个线程时,实现Runnable接口的类只须要创建一个,所以它的锁对象默认为 this
    2. 继承了Thread类的类,在创建线程时,如果使用了同步锁,那么它默认锁对象默认为 类名.class,原因在于继承了Thread的类在创建线程时,每创建一个线程创建了一个新的对象,要保证它的锁是固定的,所以它的默认锁对象就是 类名.class
    ------------------------------------------------------------------继承Thread的实体类Apples------------------------------------------------------------------
    
    package com.Ckinghan.thread;
    
    /**
     * @author Ckinghan
     *  @描述:如果类继承了Thread类,那么它在使用同步锁时,锁的对象及共享数据必须是静态的(即类对象,不管这个类被new几个,类对象只有一个)
     *              当锁加在方法上时,它的默认对象是类名.class,如Apples类在方法上加锁时,它的默认锁对象是Apples.class
     */
    public class Apples extends Thread{
    
        public Apples(String threadName){
            super(threadName);
        }
    
        /**
         * 共享数据变量,必须使用static修饰,否则,在创建线程时每一个线程都会有一个apples,且初始值都是100,就有了加锁的必要,也与
         * 最初的设计不符
         */
        private static Integer apples = 100;
    
        /**
         * 锁的对象,必须是被static修饰的且不管类被new多少个,它始终只能有一个且是不变的,否则,同步锁将失效
         */
        public static Integer lockObject = new Integer(0);
    
        @Override
        public void run() {
            while (true) {
                if(apples % 3 == 0){
                    /**
                     * 同步锁块的锁对象,建议使用 类名.class(在本类中即:Apples.class)
                     */
                    synchronized (Apples.class) {
                        if(apples > 0){
                            /**
                             * 使线程休眠30毫秒,增加出现并发的机率
                             */
                            try {
                                Thread.sleep(30);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println(this.getName()+"抢到了编号为"+apples--+"的苹果");
                        }else{
                            System.out.println("苹果已经被抢完了");
                            break;
                        }
                    }
                }else if(apples % 3 ==1){
                    /**
                     * 同步锁块的锁对象,建议使用 类名.class(在本类中即:Apples.class)
                     */
                    synchronized (Apples.class) {
                        if(apples > 0){
                            /**
                             * 使线程休眠30毫秒,增加出现并发的机率
                             */
                            try {
                                Thread.sleep(30);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println(this.getName()+"抢到了编号为"+apples--+"的苹果");
                        }else{
                            System.out.println("苹果已经被抢完了");
                            break;
                        }
                    }           
                }else{
                    //抢苹果
                    lockFunction();
                }//if end
            }//while end    
        }
    
        public synchronized static void lockFunction(){
            if(apples > 0){
                System.out.println(Thread.currentThread().getName()+"抢到了编号为"+apples--+"的苹果");
                return;
            }
            System.out.println("苹果已经被抢完了");
        }
    }
    
    
    ------------------------------------------------------------------实现了Runnable接口的实体类Apple------------------------------------------------------------------
    
    package com.Ckinghan.thread;
    
    /**
     * 创建线程的第二种方式 :实现Runnable
     * 在使用同步锁时,如果同步锁加在方法上,它默认的锁对象是this
     * 如果用在同步锁块上,它的锁对象可以自己定义,建议使用this,
     * @author Ckinghan
     *  @描述:
     */
    public class Apple implements Runnable {
    
        private Integer apples = 100;
    
        @Override
        public void run() {
            while(true){
                if(apples % 4 == 0){
                    synchronized (this) {
                        if(apples > 0){
                            try {
                                Thread.sleep(30);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println(Thread.currentThread().getName()+"抢到了编号为"+apples--+"的苹果");
                        }else{
                            System.out.println("苹果已经被抢完了");
                            break;
                        }
                    }
                }else {
                    //调用同步锁的方法抢苹果
                    lockFunction();
                }
    
    
            }
    
        }
    
        /**
         * @描述:实现Runnable接口的类,在方法上加同步锁时,默认的锁对象为this
         * @创建时间:
         */
        private synchronized void  lockFunction(){
            if(apples > 0){
                System.out.println(Thread.currentThread().getName()+"抢到了编号为"+apples--+"的苹果");
                return;
            }
            System.out.println("苹果已经被抢完了");
        }
    
    }
    
    
    ------------------------------------------------------------------测试Demo------------------------------------------------------------------
    
    package com.Ckinghan.thread;
    
    public class ApplesDemo {
    
        public static void main(String[] args) {
            /**
             *   * @描述:几个小朋友抢苹果,为防止一个编号的苹果被多个人同时抢中,加同步锁
             *              因为apple实现了Runnable接口,鉴于它的线程创建方式,在加锁时,
             *              锁的对象建议使用this,因为在方法上加同步锁,它的默认锁对象是this
             */
    //      threadRunnableApple();
    
    
    
            /**
             * @描述:几个小朋友抢苹果,为防止一个编号的苹果被多个人同时抢中,加同步锁
             *              因为apples继承了Thread类,鉴于它的线程创建方式,在加锁时,
             *              锁的对象建议使用 类名.class,因为在方法上加同步锁,它的默认锁对象是 类名.clss(如Apples.class)
             */
            extendsThreadApple();
    
        }
    
        /**
         * @描述:几个小朋友抢苹果,为防止一个编号的苹果被多个人同时抢中,加同步锁
         *              因为apples继承了Thread类,鉴于它的线程创建方式,在加锁时,
         *              锁的对象建议使用 类名.class,因为在方法上加同步锁,它的默认锁对象是 类名.clss(如Apples.class)
         * @创建时间:
         */
        public static void extendsThreadApple(){
            /**
             * 创建四个线程
             */
            Apples persion1 = new Apples("小明");
            Apples persion2 = new Apples("小二");
            Apples persion3 = new Apples("小黄");
            Apples persion4 = new Apples("小三");
            /**
             * 启动线程
             */
            persion1.start();
            persion2.start();
            persion3.start();
            persion4.start();
        }
    
        /**
         * @描述:几个小朋友抢苹果,为防止一个编号的苹果被多个人同时抢中,加同步锁
         *              因为apple实现了Runnable接口,鉴于它的线程创建方式,在加锁时,
         *              锁的对象建议使用this,因为在方法上加同步锁,它的默认锁对象是this
         * @创建时间:
         */
        public static void threadRunnableApple(){
            /**
             * 注意,实现了Runnable接口的apple类对象创建线程时,因为apple类只实例化了一次,所以不用静态的锁对象就可以,因它多个线程使用
             * 的对象只有apple一个
             */
            Apple apple = new Apple();
            /**
             * 创建四个线程
             */
            Thread persion1 = new Thread(apple,"小明");
            Thread persion2 = new Thread(apple,"小二");
            Thread persion3 = new Thread(apple,"小黄");
            Thread persion4 = new Thread(apple,"小三");
            /**
             * 启动线程
             */
            persion1.start();
            persion2.start();
            persion3.start();
            persion4.start();
    
        }
    
    }
    
    ------------------------------------------------------------------执行结果:------------------------------------------------------------------
    
    小明抢到了编号为100的苹果
    小三抢到了编号为99的苹果
    小黄抢到了编号为98的苹果
    小黄抢到了编号为97的苹果
    小黄抢到了编号为96的苹果
    小黄抢到了编号为95的苹果
    小二抢到了编号为94的苹果
    小二抢到了编号为93的苹果
    小二抢到了编号为92的苹果
    小黄抢到了编号为91的苹果
    小三抢到了编号为90的苹果
    小三抢到了编号为89的苹果
    小明抢到了编号为88的苹果
    小明抢到了编号为87的苹果
    小明抢到了编号为86的苹果
    小三抢到了编号为85的苹果
    小黄抢到了编号为84的苹果
    小二抢到了编号为83的苹果
    小黄抢到了编号为82的苹果
    小三抢到了编号为81的苹果
    小明抢到了编号为80的苹果
    小明抢到了编号为79的苹果
    小三抢到了编号为78的苹果
    小三抢到了编号为77的苹果
    小二抢到了编号为76的苹果
    小二抢到了编号为75的苹果
    小二抢到了编号为74的苹果
    小黄抢到了编号为73的苹果
    小二抢到了编号为72的苹果
    小二抢到了编号为71的苹果
    小二抢到了编号为70的苹果
    小二抢到了编号为69的苹果
    小二抢到了编号为68的苹果
    小明抢到了编号为67的苹果
    小三抢到了编号为66的苹果
    小三抢到了编号为65的苹果
    小明抢到了编号为64的苹果
    小二抢到了编号为63的苹果
    小二抢到了编号为62的苹果
    小黄抢到了编号为61的苹果
    小黄抢到了编号为60的苹果
    小黄抢到了编号为59的苹果
    小二抢到了编号为58的苹果
    小明抢到了编号为57的苹果
    小明抢到了编号为56的苹果
    小三抢到了编号为55的苹果
    小三抢到了编号为54的苹果
    小三抢到了编号为53的苹果
    小明抢到了编号为52的苹果
    小二抢到了编号为51的苹果
    小二抢到了编号为50的苹果
    小黄抢到了编号为49的苹果
    小黄抢到了编号为48的苹果
    小黄抢到了编号为47的苹果
    小二抢到了编号为46的苹果
    小二抢到了编号为45的苹果
    小二抢到了编号为44的苹果
    小明抢到了编号为43的苹果
    小明抢到了编号为42的苹果
    小明抢到了编号为41的苹果
    小三抢到了编号为40的苹果
    小三抢到了编号为39的苹果
    小三抢到了编号为38的苹果
    小明抢到了编号为37的苹果
    小明抢到了编号为36的苹果
    小明抢到了编号为35的苹果
    小二抢到了编号为34的苹果
    小二抢到了编号为33的苹果
    小黄抢到了编号为32的苹果
    小二抢到了编号为31的苹果
    小黄抢到了编号为30的苹果
    小黄抢到了编号为29的苹果
    小黄抢到了编号为28的苹果
    小黄抢到了编号为27的苹果
    小黄抢到了编号为26的苹果
    小黄抢到了编号为25的苹果
    小黄抢到了编号为24的苹果
    小黄抢到了编号为23的苹果
    小明抢到了编号为22的苹果
    小三抢到了编号为21的苹果
    小三抢到了编号为20的苹果
    小明抢到了编号为19的苹果
    小黄抢到了编号为18的苹果
    小黄抢到了编号为17的苹果
    小二抢到了编号为16的苹果
    小二抢到了编号为15的苹果
    小二抢到了编号为14的苹果
    小黄抢到了编号为13的苹果
    小黄抢到了编号为12的苹果
    小黄抢到了编号为11的苹果
    小明抢到了编号为10的苹果
    小三抢到了编号为9的苹果
    小明抢到了编号为8的苹果
    小明抢到了编号为7的苹果
    小黄抢到了编号为6的苹果
    小二抢到了编号为5的苹果
    小二抢到了编号为4的苹果
    小黄抢到了编号为3的苹果
    小黄抢到了编号为2的苹果
    小黄抢到了编号为1的苹果
    苹果已经被抢完了
    苹果已经被抢完了
    苹果已经被抢完了
    苹果已经被抢完了
    苹果已经被抢完了
    
    
    展开全文
  • 回顾一下对象创建一个线程MyThread2并继承Thread类,重写run方法class MyThread2 extends Thread{ private StringBuilder sb; public MyThread2(StringBuilder sb){ this.sb = sb; } @Override public void run...

    回顾一下对象锁

    创建一个线程MyThread2并继承Thread类,重写run方法

    class MyThread2 extends Thread{
    
        private StringBuilder sb;
    
        public MyThread2(StringBuilder sb){
            this.sb = sb;
        }
    
        @Override
        public void run() {
            //run方法持有 sb 的锁
            synchronized(sb){
                sb.reverse();
            }
            System.out.println(sb.toString());
        }
    }

    测试方法

    public class TestObjectLock {
    
        public static void main(String[] args) {
    
            // 创建 sb 对象作为下面的的锁
            StringBuilder sb = new StringBuilder("ABCDEFG");
    
            MyThread2 mt2 = new MyThread2(sb);
            mt2.start();
    
            synchronized (sb) {
                try {
                    // 线程 mt2 获得cpu执行权
                    mt2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("sb-->"+sb);
        }
    }

    结果是没有任何输出,线程产生了死锁

    分析

    线程mt2创建的时候把sb对象传入到mt2对象内部,调用start方法调用run方法,synchronized(sb){…}中使用sb作为对象锁,锁定代码块。
    回到主线程,当主线程synchronized(sb){…}中也使用sb作为对象锁,在同步代码块中mt2.join(),把cpu执行权让给mt2,主线程进入阻塞状态,但是并没有释放对象锁sb,等待mt2运行完毕。
    但是由于main线程此时拥有对象锁sb,mt2无法拥有sb的锁,导致mt2等待主线程运行完之后才能运行,
    此时就产生了这样的情况,主线程阻塞等替代mt2线程运行完才能运行,但是,mt2线程又因为要等待主线程运行完释放对象锁sb,而处在等待状态,所以双方都在等待,结果是双方线程都不运行,就产生了死锁。

    展开全文
  • 任何一个类的对象,都可以充当。 要求:多个线程必须要共用同一把。 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。 class RWindow2 extends Thread { public static in
  • 线程、线程池、Lock

    2020-07-25 10:46:03
    1.线程:Thread 创建多线程的方法一: 一个进程可以拥有多个线程 ...(2)继承Thread类的情况下 可以使用 可以通过this.setName();进行名字的设置 可以通过this.getName();进行名字的获取 (3) 在非继承Thr
  • 高级类特性 类的继承、父子类的初始化顺序、单继承性 方法的覆盖、重载、super关键字、 多态、instanceof关键字、强制类型转换、 static关键字、final关键字 数组和枚举 一维数组的应用及内存分配 多维数组的应用及...
  • 任何一个类的对象,都可以充当。要求:多个线程必须共用同一把在实现runnable接口创建多线程的方式中,可以考虑使用this来充当同步监视器。也可以考虑使用当前类.class来充当在继承thread类创建多线程的方式中,...
  • 解决线程安全方式

    2021-03-29 19:44:56
    方式一:同步代码块 synchronized(同监视器){ //需要被同步代码 ...5.在Thread继承类实现多线程方式中,慎用this关键字充当,可以考虑使用当前充当同步监视器(保证使用同一把) 例如:Run
  • 线程同步

    2021-03-16 16:52:12
    同步监视器,即,任何一个类的对象都可以充当,多个线程必须要共用同一把。 在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。在继承Thread类创建多线程的方式中,慎用this充当...
  • 方式一:同步代码块 说明: ...在继承Thread类创建多线程方式中,慎用this充当同步监视器,考虑使用当前充当同步监视器。 方式二:同步方法 如果操作共享数据代码完整声明在一个方法中,我们不
  • java线程同步机制

    2020-12-10 20:49:54
    1.背景 2.Java解决方案:同步机制 方式一:同步代码块 synchronized(同步监视器){ //需要被同步代码 } 说明: ...1.操作共享数据代码,...4.在继承Thread类创建多线程方式中,慎用this充当同步监视器,考虑使
  • 继承Thread类 实现Runnable接口 匿名内部 callable接口 线程安全: ​ 同步代码块 ​ 同步方法 ​ 同步资源:this,类名.class 内容: 能够说出线程状态 对线程状态有一定认识 能够理解线程通信...
  • 然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定...
  • 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造(Constructor)方法初探 181 7.9.2 如何使用构造方法 182 7.9.3 留个无参数的构造方法——给重要...
  • 继承Thread类创建多线程方式中慎用this充当监视器,考虑用当前充当监视器 Runnable 继承thread类同步代码块 2、同步方法 3、jdk1.5后 同步lock 显示加锁释放 释放在finally中 用法 ReentrantLock...
  • 实现Runnable接口的同步: ...继承Thread类的同步: 在继承Thread中,创建Thread类的对象有三个。在synchronized中同步监视器要保证多个线程共用同一把,所以不可以使用this。 而实现Runnable可以使用this ...
  • 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造(Constructor)方法初探 181 7.9.2 如何使用构造方法 182 7.9.3 留个无参数的构造方法——给重要...
  • 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造(Constructor)方法初探 181 7.9.2 如何使用构造方法 182 7.9.3 留个无参数的构造方法——给重要...
  • 基于JAVA搜索引擎 lucene-2.2.0

    热门讨论 2011-11-15 07:47:11
    必须深入地理解IndexWriter索引器初始化的过程,以及在构造一个IndexWriter索引器过程中涉及到的一些其他的类,应该深入研究这些相关的类的定义。这样才能有助于深化IndexWriter索引器构造的原理机制。 可见,...
  • 继承Thread类 实现Runnable接口 thread1.join()方法:等待线程1执行完后才接着执行 二、Sysnchronized两种用法(对象类锁) 对象 包括方法(默认对象为this当前实例对象)和同步代码块(自己指定...
  • ------Java培训、Android...Thread构造器接收Runnable接口实现对象,数据共享。多线程在共享数据操作上安全问题,同步技术处理安全问题,synchronized 同步方法,是对象,方法默认就是this,静态方法就是类名.
  • java之多线程

    2019-09-13 09:29:48
    1 线程两种实现方式 A 继承thread类 B 实现runnable接口 2 同步 synchronized(对象) { } 非静态的锁对象:方法中都能共享一个对象this 静态的锁对象:所有对象都能共享一个对象,.class 3 实例 ...
  • 同步代码块处理Runnable接口线程安全问题 synchronized(同步监视器){ ...要求:多个线程必须共用一把继承Thread类则不能使用对象,只能用 抢票例子: public class SynchronizedTest { publi...
  • Java学习笔记——5

    2021-02-23 10:53:47
    线程同步 方式一.同步代码块 synchronized(同步监视器){ 、、、需要同步代码,即操作共享数据...但是在继承Thread类创建多线程方式中,慎用this充当监视器,考虑使用当前作为监视器 方式二.同步方法 ...
  •  a:继承Thread类,复写该类的run方法 b:实现Runnable接口,实现run方法,然后把该类作为Thread构造方法的参数2.synchronized是放在方法上也可以用于一个同步代码块,放在非static方法上,this,放在static方法...
  • 任何一个类的对象,都可以充当。要求:多个线程必须共用同一把在实现runnable接口创建多线程的方式中,可以考虑使用this来充当同步监视器。也可以考虑使用当前类.class来充当在继承thread类创建多线程的方式中,...
  • java-day7基础

    2020-11-29 11:07:28
    同步监视器,俗称,任何一个类的对象都可以充当。 要求:多个线程必须要共用同一把 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器 synchronized(this) 在继承Thread类创建...
  • 零基础Java入门课程

    2020-12-06 18:54:17
    高级类特性 类的继承、父子类的初始化顺序、单继承性 方法的覆盖、重载、super关键字、 多态、instanceof关键字、强制类型转换、 static关键字、final关键字 数组和枚举 一维数组的应用及内存分配 多维数组的应用及...
  • 高级类特性 类的继承、父子类的初始化顺序、单继承性 方法的覆盖、重载、super关键字、 多态、instanceof关键字、强制类型转换、 static关键字、final关键字 数组和枚举 一维数组的应用及内存分配 多维数组的应用及...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

继承thread的类的this锁