由于线程的执行是CPU随机调度的,比如我们开启10个线程,这10个线程并不是同时执行的,而是CPU快速的在这10个线程之间切换执行,由于切换速度极快使我们感觉同时执行罢了。
线程同步问题往往发生在多个线程调用同一方法或者操作同一变量,但是我们要知道其本质就是CPU对线程的随机调度,CPU无法保证一个线程执行完其逻辑才去调用另一个线程执行。比如线程A首先获取到CPU资源,但是没有将代码块中的代码执行完的时候线程B获取到了CPU资源,这时候就会去执行线程B的代码块,如果线程A和B都在操作同一个资源,就会出现错误数据,所以会产生安全问题。
解决方案:
可使用同步代码块和同步方法来解决
同步代码块:
public class Demo { public void method1() { synchronized (this) { System.out.print("山"); System.out.print("东"); System.out.print("张"); System.out.print("学"); System.out.print("友"); System.out.print("\r\n"); } } }
同步方法:
public class Demo { public synchronized void method2() { System.out.print("s"); System.out.print("d"); System.out.print("z"); System.out.print("x"); System.out.print("y"); System.out.print("\r\n"); } }
静态同步代码块:
public class Demo { public static void method1() { synchronized (Demo.class) { System.out.print("山"); System.out.print("东"); System.out.print("张"); System.out.print("学"); System.out.print("友"); System.out.print("\r\n"); } } }
静态同步方法:
public class Demo { public static synchronized void method2() { System.out.print("s"); System.out.print("d"); System.out.print("z"); System.out.print("x"); System.out.print("y"); System.out.print("\r\n"); } }
这里说明一下:
/* * 静态同步方法 和 非静态同步方法的锁对象 * 静态方法: 锁对象: 该类的字节码文件对象. 也就是上面的Demo.class 非静态方法: 锁对象: this */
总结:普通同步方法的锁是this,静态同步函数的锁是类的字节码文件,
扫描二维码关注公众号,回复:
1516251 查看本文章
当前类实例对象,同步代码块锁可以自己定义,只要保证操作同一数据的线程使用的是同一把锁即可。