• 关于java多线程


    package testSynchronized;
    /** * * 当使用this也就是该文件中的testclass对象作为对象锁时, * 两个线程都使用该对象锁访问该对象的同步代码块, * 是顺序执行的, * 也就是说当一个线程使用testclass对象对这段同步代码块上锁了以后, * 另一个线程无法再使用testclass对象进入该同步代码块 * 理解: * 因为该锁标记对象已经被标记为正在使用,所以只能排队 * */ class TestClass { public void f(){ synchronized(this){ for(int i = 0 ; i < 1000 ; i ++){ System.out.println("i: " + i ); } } } } class ThreadTest extends Thread { private TestClass testclass ; public ThreadTest(TestClass testclass) { this.testclass = testclass ; } @Override public void run() { testclass.f(); } } public class TestSynchroinzed { public static void main(String[] args) { TestClass testclass = new TestClass() ; ThreadTest thread1 = new ThreadTest(testclass) ; ThreadTest thread2 = new ThreadTest(testclass) ; thread1.start(); thread2.start(); } }

    在来一个:

    package testSynchronized;
    /**
     * 
     * 在该类中测试两个线程使用不同的锁对象,观察能不能同时访问一个同步代码块
     *
     * 出现的结果和TestSynchronized相反。这两个线程可以同时进入该同步代码块执行。
     * 
     * why ???????
     * 
     * 测试结果表明: 
     *     使用同一对象锁的多个线程需要排队访问
     *     使用不同对象锁的多个线程可以同时访问(完全是不同的对象,不同的内存空间,当然不存在线程问题)
     * 
     * 似乎明白了:
     *  使用this作为锁标记,当一个线程使用这个锁标记锁住某些
     *  (可以使用一个线程同时访问使用一个对象标记锁的多个同步代码块,
     *  那么这个线程就使用该对象锁住了多个同步代码块)代码块后,
     *  其他的线程准备执行这个对象的这个同步代码块时,
     *  会被告知这个this对象正在被使用锁住一些同步代码,还没有被释放,所以无法使用该锁进入同步代码块。
     *  只有使用该锁锁住的所有同步代码块都执行结束的后,
     *  其他的线程才能够重新使用该对象作为锁标记进入同步代码块 
     *  
     *  但是如果调用的就是不同的对象方法,
     *  那么就不会存在同步的问题,
     *  因为完全是两个不同的方法,不同的内存空间。
     */
    class TestClass1 {
        public void f(){
            synchronized(this){
                while(true);
            }
        }
        public void f2(){
            synchronized(this){
                for(int i = 0 ; i < 100 ; i ++){
                    System.out.println("################");
                }
            }
        }
    }
    class ThreadTest1 extends Thread {
        private TestClass1 testclass ;
        public ThreadTest1(TestClass1 testclass) {
            this.testclass = testclass ;
        }
        @Override
        public void run() {
            testclass.f();
        }
    }
    class ThreadTest2 extends Thread {
        private TestClass1 testclass ;
        public ThreadTest2(TestClass1 testclass) {
            this.testclass = testclass ;
        }
        @Override
        public void run() {
            testclass.f2();
        }
    }
    public class TestSynchronized2 {
        public static void main(String[] args) {
            TestClass1 testclass = new TestClass1() ;
            TestClass1 testclass2 = new TestClass1() ;
            ThreadTest1 thread1 = new ThreadTest1(testclass) ;
            ThreadTest2 thread2 = new ThreadTest2(testclass) ;
            thread1.start();
            thread2.start();
        }
    }
    package test;
    
    /**
     * 
     * 测试同步对象使用Class对象
     *
     * 总结: 注:每一个对象都有且仅有一个对象锁 
     * 1. 当同步代码块中使用的对象是一个类的普通对象, 那么当一个线程进入该同步代码块
     * (或同步方法,区别不大,只是同步方法默认使用的锁对象是this) 并获取该对象的锁后(前提是该对象的锁是空闲的), 其他线程使用同一锁对象 (例如:
     * 当两个线程使用同一对象并都调用该对象的一个同步方法时) 无法进入该同步代码块, 因为该代码块的锁对象的锁已经被先来的线程占用
     * (注意,是该锁对象的锁,每一个对象都有唯一的一个锁,你能否进入同步代码块的唯一条件是你有没有获得锁对象的锁),现在的情况是,
     * 一个线程已经占用了同步代码块的锁对象的锁,那么锁对象的其他非同步方法可以被其他线程访问(前提是该对象有非同步方法),
     * 该锁对象的其他同步方法不能被其他线程访问。
     * 
     * 2. 当同步代码块使用的锁对象是Class对象时(例如: TestClass.class,同步静态方法和使用Class对象的同步代码块的效果是一样的)。
     * 当一个线程进入同步代码块(或者调用了静态同步方法)时,它获取了该Class对象的锁,那么其他的线程将不能访问该类的同步静态方法,
     * 非同步静态方法可以正常访问 。
     */
    
    class TestClass {
        /**
         * 一个线程访问f,一个线程访问staticF,理论上当第一个线程访问f时就会获得TestClass.class对象锁
         * 那么另一个线程无法访问静态方法。
         */
        public synchronized static void staticF() {
            System.out.println("执行staticF");
        }
    
        public void f() {
            synchronized (TestClass.class) {
                System.out.println("调用f()方法 ");
                // 使用无限循环让当前线程一直占用TestClass.class对象锁
                while (true)
                    ;
            }
        }
    
        /**
         * 该方法的作用是测试当一个线程获得了某个对象的锁后, 其他的线程能不能访问该对象的非同步方法或者同步代码块
         */
    
        public void f3() {
            synchronized (this) {
                System.out.println("执行了f3()");
                /**
                 * 下面是无限循环,目的是让当前线程一直占用着this这个对象的锁,
                 * 以查看其他线程能不能访问f4()这个非同步方法和f5()这个同步方法
                 */
                while (true)
                    ;
            }
        }
    
        public void f4() {
            System.out.println("执行了非同步方法f4()");
        }
    
        public synchronized void f5() {
            System.out.println("执行了非同步方法f5()");
        }
    }
    
    class Thread1 extends Thread {
        private TestClass testclass;
    
        public Thread1(TestClass testclass) {
            this.testclass = testclass;
        }
    
        @Override
        public void run() {
            testclass.f();
        }
    }
    
    class Thread2 extends Thread {
        @Override
        public void run() {
            TestClass.staticF();
        }
    }
    
    class Thread3 extends Thread {
        private TestClass testclass;
    
        public Thread3(TestClass testclass) {
            this.testclass = testclass;
        }
    
        @Override
        public void run() {
            testclass.f3();
        }
    }
    
    class Thread4 extends Thread {
        private TestClass testclass;
    
        public Thread4(TestClass testclass) {
            this.testclass = testclass;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            testclass.f4();
        }
    }
    
    class Thread5 extends Thread {
        private TestClass testclass;
    
        public Thread5(TestClass testclass) {
            this.testclass = testclass;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            testclass.f5();
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            TestClass testclass = new TestClass();
            /*
             * Thread1 thread1 = new Thread1(testclass) ; Thread2 thread2 = new
             * Thread2() ; thread1.start(); thread2.start();
             */
            Thread3 thread3 = new Thread3(testclass);
            // Thread4 thread4 = new Thread4(testclass) ;
            Thread5 thread5 = new Thread5(testclass);
            thread3.start();
            // thread4.start() ;
            thread5.start();
    
        }
    }
  • 相关阅读:
    [root@py ~]# watch -n 1 ifconfig 求解释
    25 个常用的 Linux iptables 规则
    linux shell 字符串操作(长度,查找,替换)详解
    linux高级网络配置 ip别名,接口绑定
    初始版本控制工具-Git
    详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ”
    wireshark_users
    wireshark抓包基础步骤及PPPOE拨号抓包过程分析
    ARP原理与ARP攻击
    PPPOE 详解
  • 原文地址:https://www.cnblogs.com/caiyao/p/4663759.html
Copyright © 2020-2023  润新知