Synchronized关键字的使用

大前提:全部线程是没有前后顺序的,若是引入同步锁,谁先得到对象锁,谁先执行ide

 

线程实现方式:测试

1.继承Thread类,重写run方法;this

2.实现runnable接口,实现其run方法。线程

 

启动方式:对象

    调用线程的start方法启动线程,start方法为线程准备好系统资源,而后调用run方法执行代码逻辑。继承

经常使用方法:接口

   Object对象方法:资源

     wait和notify方法:这两个方法定义在Object类中,final方法,没法重写,这两方法要求被调用时线程已得到对象的锁,所以须要放在synchronized方法或块中调用。当执行wait方法时,线程会释放对象的锁,线程会处于等待状态;调用notify时,会随机唤醒一个等待的线程(可是不会立马被执行),此唤醒的线程与其余线程竞争对象锁。get

    notifyAll方法:也须要在静态方法或静态代码块中执行,会唤醒全部等待的线程跟其余线程进行锁的竞争;同步

    

当前线程对象的方法

    join:用于将当前线程插入到正在执行的线程,当前线程得到对象锁并执行完后(销毁后)才会继续进行原来正在执行线程未完成的操做。

 

静态方法:

    Thread.sleep方法:会让当前线程休眠指定毫秒时间,整个过程不会释放对象锁。

    Thread.yield方法:经当前线程从新置于就绪状态,整个过程不会释放对象锁。

 

三种使用场景:

    1.修饰静态方法:表示对类(Class对象)的枷锁,在进入该静态方法前,当前线程须要得到该类的锁。

        一个线程访问该Class对象的任何同步静态方法,其余线程没法访问该Class对象的任何同步方法。

    2.修饰普通方法:表示对类实例的加锁,在进入普通方法前,当前线程须要得到该实例的锁(若是是当前类的不一样对象,则不会出现同步显现);

    都一个普通方法用synchronized进行修饰,表示对对象加锁,当一个线程调用该方法时,其余线程没法访问该方法,指导第一个线程执行完或抛出异常释放掉对象锁,其余线程才有可能访问该同步方法。

    若是一个对象有多个同步方法,当一个线程访问某个同步方法时,其余线程也是没法访问该对象的任何同步方法的。

    3.修饰代码块:表示对指定对象枷锁,在进入代码块前,当前线程须要得到该指定对象的锁

 

同步测试代码以下:

/**
 * 同步关键字的使用
 * 全部线程是没有优先级的(线程执行没有前后顺序),若是引入同步锁,谁先得到对象锁,谁先执行
 *
 * @author kevin
 * @email ly_triangle@126.com
 * @date 2018年3月8日
 */
public class SynchronizeDemo {

    /**
     * 同步静态方法1
     */
    public synchronized static void synchronizedStaticMethod1() {
        try {
            System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod1");
            Thread.sleep(2000l);
            System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod1……");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 同步静态方法2
     */
    public synchronized static void synchronizedStaticMethod2() {
        System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod2");
    }

    /**
     * 同步普通方法1
     */
    public synchronized void synchronizedMethod1() {
        try {
            System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1");
            Thread.sleep(2000l);
            System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1……");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 同步普通方法2
     */
    public synchronized void synchronizedMethod2() {
        System.out.println(Thread.currentThread().getName() + ":synchronizedMethod2");
    }

    /**
     * 非同步普通方法1
     */
    public void method1() {
        try {
            System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1");
            Thread.sleep(2000l);
            System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1……");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 非同步普通方法2
     */
    public void method2() {
        System.out.println(Thread.currentThread().getName() + ":synchronizedMethod2");
    }

    /**
     * 同步代码块1
     */
    public void synchronizedCodes1() {
        try {
            synchronized (this) {
                System.out.println(Thread.currentThread().getName() + ":synchronizedCodes1");
                Thread.sleep(2000l);
                System.out.println(Thread.currentThread().getName() + ":synchronizedCodes1……");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 同步代码块2
     */
    public void synchronizedCodes2() {
        System.out.println(Thread.currentThread().getName() + ":synchronizedCodes2 will begining……");
        synchronized (this) {
            System.out.println(Thread.currentThread().getName() + ":synchronizedCodes2");
        }
    }

    public static void main(String[] args) {

        /*测试非同步普通方法
        * 第二个线程不会等第一个结束就开始执行了
        */
        SynchronizeDemo demo = new SynchronizeDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.method1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.method2();
            }
        }).start();

       /* 测试同步静态方法
       *第一个方法执行完毕后才会执行第二个方法
       * 除非不是同一个类
       */
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         SynchronizeDemo.synchronizedStaticMethod1();
        //     }
        // }).start();
        //
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         SynchronizeDemo.synchronizedStaticMethod2();
        //     }
        // }).start();

        /*测试同步普通方法
        * 第一个方法执行完毕才会执行第二个方法
        * 除非不是同一个对象
        */
        // SynchronizeDemo demo = new SynchronizeDemo();
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         demo.synchronizedMethod1();
        //     }
        // }).start();
        //
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         demo.synchronizedMethod2();
        //     }
        // }).start();

        /*测试同步代码块
        * 第一个代码块执行完才会执行第二个代码块
        * 除非不是同一个对象
        */
        // SynchronizeDemo demo = new SynchronizeDemo();
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         demo.synchronizedCodes1();
        //     }
        // }).start();
        //
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         demo.synchronizedCodes2();
        //     }
        // }).start();
    }
}

 

wait和notify方法测试:

public class ThreadDemo {

    public synchronized void run() {
        try {
            for (int i = 0; i < 5; i++) {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + "  ::" + i);
                if (2 == i) {
                    this.wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void run1() {
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + "  " + i);
            }
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {

        ThreadDemo demo = new ThreadDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.run();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.run1();
            }
        }).start();
    }
}

结果以下:
        Thread-0  ::0
        Thread-0  ::1
        Thread-0  ::2
        Thread-1  0
        Thread-1  1
        Thread-1  2
        Thread-1  3
        Thread-1  4
        Thread-0  ::3
        Thread-0  ::4

join方法测试:

public class ThreadJoinDemo {

    public synchronized void runDemo(String threadName, int i) {
        System.out.println(threadName + ":" + i);
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadJoinDemo demo = new ThreadJoinDemo();
        // 定义子线程
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    demo.runDemo(Thread.currentThread().getName(), i);
                }
            }
        });

        for (int i = 0; i < 5; i++) {
            demo.runDemo(Thread.currentThread().getName(), i);
            if (2 == i) {
                thread.start();

                //让主线程释放锁,子线程得到对象锁并执行完后才会接着执行主线程未完的操做
                thread.join();
            }
        }
    }
}

结果以下:
        main 0
        main 1
        main 2
        Thread-0:0
        Thread-0:1
        Thread-0:2
        Thread-0:3
        Thread-0:4
        main 3
        main 4
相关文章
相关标签/搜索