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

关于多线程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架构,我这边给大家准备了一些关于Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分布式、高并发、性能调优、微服务等架构技术的资料,希望能帮助一些技术遇到了瓶颈但是你又拒绝平庸,期待蜕变,想进入一线互联网公司或者给自己涨薪的程序大咖!

欢迎大家加入java技术交流群:1007476384,免费分享Spring框架、Mybatis框架SpringBoot框架、SpringMVC框架、SpringCloud微服务、Dubbo框架、Redis缓存、RabbitMq消息、JVM调优、Tomcat容器、MySQL数据库教学视频及架构学习思维导图

猜你喜欢

转载自blog.csdn.net/weixin_43640104/article/details/90214634