同步关键字怎么在Java中使用?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
首先来回顾一下同步的基本使用:
- <李>
同步代码块,被修饰的代码成为同步语句块,其作用的范围是调用这个代码块的对象,我们在用同步关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步。这叫减小锁的粒度,使代码更大程度的并发。
李> <李>同步的方法,被修饰的方法成为同步方法,其作用范围是整个方法,作用对象是调用这个方法的对象。
李> <李>同步静态方法,修饰一个静态静态方法,其作用范围是整个静态方法,作用对象是这个类的所有对象。
李> <李>同步的类,其作用范围是同步后面括号括起来的部分同步(className.class),作用的对象是这个类的所有对象。
李> <李>同步(),()中是锁住的对象,同步(这)锁住的只是对象本身,同一个类的不同对象调用的同步的方法并不会被锁住,而同步(className.class)实现了全局锁的功能,所有这个类的对象调用这个方法都受到锁的影响,此外()中还可以添加一个具体的对象,实现给具体对象加锁。
synchronized (对象),{ ,//在同步代码块中对对象进行操作, }
<强>同步关键字与线程安全
强>以为用了同步关键字包住了代码就可以线程同步安全了。测试了下,发现是完全的错了.synchronized必须正确的使用才是真正的线程安全,虽然知道这种写法,一直以为却由于懒而用了错误的方法。
看来基础还没有打好。仍需复习加强!工作中犯这种错误是不可原谅的,要知道使用同步关键字的地方都是数据敏感的!汗一把…
先贴代码:
package com,, , {public class  ThreadTest ,public static  void main (String [], args), {, MyThread 才能;m1 =, new MyThread (1),, MyThread 才能;m2 =, new MyThread; (2), m1.start才能(),, m2.start才能(),, }大敌; }, , final class  MyThread extends Thread  {, ,private int val; , ,public MyThread (int v), {, val 才能=,v,, }大敌; ,//这种做法其实是非线程安全的, ,public synchronized void  print1 (int v), {, for 才能;(int 小姐:=,0;,小姐:& lt;, 100;,我+ +),{, ,,System.out.print (v),, ,,}, }大敌; , ,public void  print2 (int v), {,//线才能程安全, synchronized 才能;(MyThread.class), {, ,,for (int 小姐:=,0;,小姐:& lt;, 100;,我+ +),{, ,,,System.out.print (v),, ,,}, ,,}, }大敌; , ,public void  run (), {, print1 (val);才能,//才能,print2 (val);, }大敌; }
还是为了偷懒,汗一把……程序员总是懒的吧。能少写就少写。我把MyThread写成了一个匿名的最终的内部类,方便调用。它用了最直接的继承线程来实现一个线程类,定义需要运行的运行()方法。
首先注释了print2()方法,看看print1()的结果如何.print1()是一个使用了同步关键字定义的方法,我一直以为这样也可以实现线程安全。殊不知,我错了。
我们来直接运行主要()方法。控制台打印结果如下:
代码如下:
1212111121212121212121212121212121212121222222212121212…
是一连串1和2交叉打印的结果。而我主方法中是先运行m1再运行m2的,显示没有做到线程同步!
MyThread m1 =, new MyThread (1),, MyThread m2 =, new MyThread; (2), m1.start (),, m2.start ();
接下来我们注释掉运行方法中的print1(),运行print2 ();
控制台打印如下:
代码如下:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
线程果然是安全了,一直以为也知道这种写法,但由于这种写法代码稍微多点也就没怎么考虑,今天才意识到这种错误。看来有时候不懒还是有好处的。打好基础很重要。纠正的长期以来的一个错误。
下面我们来看看具体原因。
同步关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,同步可作用于实例变量,对象引用(对象引用),静态函数和类文字(类名称字面常量)身上。