赞
踩
synchronized 是一个关键字。
synchronized 加到 static 方法前面是给class 加锁,即类锁;
synchronized 加到非静态方法上是给对象上锁,即对象锁。
对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。
所以我们用代码来演示下
首先准备工作,先创建一个Task类 新建三个方法其中两个 是static修饰静态的。
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 1:37 下午
- * @Version: 1.0
- */
- public class Task {
- public synchronized static void TaskA() {
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
- }
-
- public synchronized static void TaskB() {
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
- }
-
- public synchronized void TaskC() {
-
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", begin");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- System.out.println("ClassName = " + Thread.currentThread().getName() + ", end");
-
- }
第二步 创建三个类来调用各自Task中的方法(也就像IG baolan说:“各过各的”)咱们各调各的。
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 2:00 下午
- * @Version: 1.0
- */
- public class ThreadA extends Thread{
- private Task TTask;
-
- public ThreadA(Task tk){
- TTask = tk;
- }
-
- public void run() {
- TTask.TaskA();
- }
- }
-
-
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 1:46 下午
- * @Version: 1.0
- */
- public class ThreadB extends Thread{
-
- private Task TTask;
-
- public ThreadB(Task tk){
- TTask = tk;
- }
-
- public void run() {
- TTask.TaskB();
- }
-
- }
-
-
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 2:01 下午
- * @Version: 1.0
- */
- public class ThreadC extends Thread{
-
- private Task TTask;
-
- public ThreadC(Task tk){
- TTask = tk;
- }
-
- public void run() {
- TTask.TaskC();
- }
- }
第三步创建一个main方法咱们来测试一下
- public static void main(String[] args) {
- Task TTask = new Task();
- ThreadA ta = new ThreadA(TTask);
- ThreadB tb = new ThreadB(TTask);
- ThreadC tc = new ThreadC(TTask);
-
- ta.setName("A");
- tb.setName("B");
- tc.setName("C");
-
- ta.start();
- tb.start();
- tc.start();
- }
结果如下,我们可以清楚的看到TaskA和TaskB是顺序执行的,而TaskC是和TaskA、TaskB异步执行的。因为TaskA、TaskB是加了static修饰的属于类锁,TaskC是对象锁。
我们来继续测试,测试同步调用TaskC 看看TaskC会不会顺序执行,我们修改ThreadA和ThreadB,让这两个都去调用TaskC方法
然后咱们main也要改下如下
- public static void main(String[] args) {
-
- Task TTaska = new Task();
- Task TTaskb = new Task();
- ThreadA ta = new ThreadA(TTaska );
- ThreadB tb = new ThreadB(TTaskb );
-
-
- ta.setName("A");
- tb.setName("B");
-
- ta.start();
- tb.start();
- }
结果如下,可以看出 ThreadA和ThreadB在调用方法锁TaskC时是异步执行的。
测试完了方法锁,咱们在试试类锁
将ThreadA和ThreadB中调用方法都改成调用TaskA。mian方法不用变执行即可。
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 2:00 下午
- * @Version: 1.0
- */
- public class ThreadA extends Thread{
- private Task TTask;
-
- public ThreadA(Task tk){
- TTask = tk;
- }
-
- public void run() {
- TTask.TaskA();
- }
- }
-
-
-
- /**
- * @Title: dmdemo
- * @Description:
- * @author: liaryank
- * @Date: 2020/7/23 1:46 下午
- * @Version: 1.0
- */
- public class ThreadB extends Thread{
-
- private Task TTask;
-
- public ThreadB(Task tk){
- TTask = tk;
- }
-
- public void run() {
- TTask.TaskA();
- }
-
- }
执行结果如下,从结果我们可以看出,方法上加了静态static 成为类锁后会顺序执行。
我们来小小总结一下:
类锁对该类的所有对象都能起作用,而对象锁不能。
多线程访问某类中synchronized修饰的静态和非静态方法时是可以异步执行的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。