美文网首页JavaJava 杂谈
Java多线程中synchronized关键字的使用方法

Java多线程中synchronized关键字的使用方法

作者: 4553675200ad | 来源:发表于2019-05-14 20:54 被阅读0次

    关于多线程Thread方法的几点总结,

    1. isAlive方法判断线程是否存活 ,wait方法传入参数0无限期等待
    2. yield方法让出cpu执行权大家再次公平竞争
    3. join方法等待线程执行完一起运行,比如子线程运行循环累加,主线程运行at.join(0),一直等他累加完,主线程在运行下面的打印语句,相当于主线程在等待子线程的运行完成
    4. 守护进程不主导虚拟机的运行,守护进程设置方法为thread.daemon(true),必须在start方法前,不然抛错且无效,如果main中只有设置守护线程且start,不论线程中如何写死循环,程序直接结束
    5. 多线程中的关于synchronize关键字使用
      注意notify wait以及相对应的两个all方法都是Object对象的方法,必须拿到锁之后才能执行这些方法

    指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java 代码解释请看注释

    package com.gzr.study;
    
    /**
     * 
     * @author gzr
     *  synchronized 关键字
     *  制定加锁对象 :指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java
     *  直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁  TestSyn2.java
     *  直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java
     */
    
    public class TestSyn implements Runnable{
    
        /**
         * testSyn为实例对象作为锁
         */
        static TestSyn testSyn=new TestSyn();
        static int i=0;
    
        public static void main(String[] args) throws InterruptedException {
            Thread t1=new Thread(testSyn);
            Thread t2=new Thread(testSyn);
            t1.start();t2.start();
            /**
            * t1 t2执行完之后 主线程在运行打印语句
            */
            t1.join();t2.join();
            System.out.println(i);
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int j=0;j<100;j++) {
                synchronized (testSyn) {
                    i++;
                }
            }
        }
    
    }
    
    

    直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁 TestSyn2.java

    package com.gzr.study;
    
    
    /**
     * 
     * @author gzr
     *  synchronized 关键字
     *  制定加锁对象 :指定对象加锁,进入同步代码前需要获得给定对象的锁 TestSyn.java
     *  直接作用于实例方法:相当于对当前实例加锁 需要获得当前实例的锁  TestSyn2.java
     *  直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java
     */
    
    public class TestSyn2 implements Runnable{
    
        /**
         * testSyn为实例对象作为锁
         */
        static TestSyn2 testSyn=new TestSyn2();
        static int i=0;
    
        public static void main(String[] args) throws InterruptedException {
            Thread t1=new Thread(testSyn);
            Thread t2=new Thread(testSyn);
            /*
             * 这是错误的调用方法因为作用于实例方法上的,必须是同一实例才能同步,这里new到两个对象不会产生同步效果
             * Thread t1=new Thread(new TestSyn2());
            Thread t2=new Thread(new TestSyn2());*/
            t1.start();t2.start();
            t1.join();t2.join();
            System.out.println(i);
        }
    
        /**
         * synchronized关键字作用于方法上
         */
        public synchronized void increase() {
            i++;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int j=0;j<10000;j++) {
                increase();
            }
        }
    
    }
    
    

    直接作用于静态方法:相当于对当前类加锁,进入同步代码钱需要获得当前类的锁 SimpleWaitNotify.java

    package com.gzr.study;
    
    
    public class SimpleWaitNotify {
        final static Object object=new Object();
    
        public static class T1 extends Thread{
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                /**
                 * object.wait();放在这里运行会报错
                 */
                synchronized (object) {
                    System.out.println(System.currentTimeMillis()+",T1 start");
                    try {
                        System.out.println(System.currentTimeMillis()+",T1 wait");
                        /**
                         * 注意wait和notify等方法都必须在你拿到锁之后才有资格做
                         * t1 放弃刚才拿到的锁对象,大家重新开始竞争锁 
                         * 在哪wait就在哪醒
                         */
                        object.wait();
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                    System.out.println(System.currentTimeMillis()+",T1 End");
                }
            }
    
        }
    
        public static class T2 extends Thread{
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                synchronized (object) {
                    System.out.println(System.currentTimeMillis()+",T2 start");
                    try {
                        /**
                         * notify会随机唤醒一个拥有当前锁的监视器的进程,这里只有t1所以唤醒t1
                         * notify唤醒t1 让他有机会拿到锁执行下去
                         */
                        object.notify();
                        System.out.println(System.currentTimeMillis()+",T2 notify");
                        System.out.println(System.currentTimeMillis()+",T2 End");
                        /**
                         * 完了之后休眠2秒,t2 End两秒之后 t1 End被打印
                         */
                        Thread.sleep(2000);
                        /**
                         * t2 放弃刚才拿到的锁对象,大家重新开始竞争锁 
                         * 在哪wait就在哪醒
                         */
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
    
                }
            }
    
        }
    
        public static void main(String[] args) {
            Thread t1=new T1();
            Thread t2=new T2();
            t1.start();t2.start();
            /**
             * 运行结果如下
             * 1512191804823,T1 start
                1512191804824,T1 wait
                1512191804824,T2 start
                1512191804824,T2 notify
                1512191804824,T2 End
                1512191806825,T1 End
    
                T2 End两秒后T1 End
             */
        }
    
    }
    
    

    相关文章

      网友评论

        本文标题:Java多线程中synchronized关键字的使用方法

        本文链接:https://www.haomeiwen.com/subject/ipzeaqtx.html