版权声明:版权归 爱装逼的文艺小青年所有 https://blog.csdn.net/toyota_rav4/article/details/84963372
synchronized同步方法的弊端
当A线程调用对象中的同步方法时执行任务的时间很长,这样B线程要一直晾着,啥事也干不了。这就是弊端!
假设A,B,C,D等多位顾客正在超市收银台结账,A正在结账的时候发现自己钱没带,需要回家去拿,剩下的顾客如果一直等着A回家拿完钱结完账才能买单,那就很耽误后面顾客的时间。这时候应该让后面的人结账走人。
放到线程中就是 A线程任务花费时间长,应该让其他线程先执行。
package com.demo15;
import java.text.SimpleDateFormat;
public class MyObject {
synchronized public void myTaskA(){
try {
System.out.println("myTaskA");
System.out.println("myTaskA即将进入睡眠,时间=" +
SimpleDateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
Thread.sleep(5000);
System.out.println("myTaskA即将结束睡眠,时间=" +
SimpleDateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void myTaskB(){
System.out.println("myTaskB");
}
}
package com.demo15;
public class ThreadA extends Thread {
MyObject myObject = new MyObject();
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.myTaskA();
}
}
package com.demo15;
public class ThreadB extends Thread {
MyObject myObject = new MyObject();
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.myTaskB();
}
}
package com.demo15;
import java.text.SimpleDateFormat;
public class Run {
public static String begintime ;
public static void main(String[] args) {
MyObject myObject = new MyObject();
ThreadA threadA = new ThreadA(myObject);
ThreadB threadB = new ThreadB(myObject);
threadA.start();
threadB.start();
}
}
运行结果:
myTaskA
myTaskA即将进入睡眠,时间=2018-12-11 23:06:21
myTaskA即将结束睡眠,时间=2018-12-11 23:06:26
myTaskB
通过结果可知,A执行同步方法花费了5秒,这期间B什么也不能做!
作出以下的修改:
package com.demo15;
import java.text.SimpleDateFormat;
public class MyObject {
public void myTaskA(){
try {
synchronized(this){
System.out.println("myTaskA");
}
System.out.println("myTaskA即将进入睡眠,时间=" +
SimpleDateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
Thread.sleep(5000);
System.out.println("myTaskA即将结束睡眠,时间=" +
SimpleDateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void myTaskB(){
System.out.println("myTaskB");
}
}
此时的运行结果为:
myTaskA
myTaskB
myTaskA即将进入睡眠,时间=2018-12-11 23:20:05
myTaskA即将结束睡眠,时间=2018-12-11 23:20:10
当A执行完同步代码块之后,立即释放锁,让其他线程执行!然后再获取CPU资源来运行后续的花费事件长的任务。
通过上面的例子我们可以看到 使用同步代码块 相对使用同步方法的优势!