赞
踩
synchronized
关键字涉及到锁的概念,在java中,synchronized锁大家又通俗的称为:方法锁,对象锁 和 类锁 。关于锁只有以下两点:
synchronized
方法时,由于对象锁的存在,所有加synchronized
的方法都不能被访问(前提是在多个线程调用的是同一个对象实例中的方法)synchronized
,此类的所有的实例化对象在调用该方法时,共用同一把锁,称之为类锁synchronized
修饰普通方法,锁定的是当前对象,
- public class SyncTest {
- public synchronized void methon(){
- //方法体
- }
- }
一次只能有一个线程进入同一个对象实例的method()
方法。
- public class SyncObjectTest implements Runnable{
- private int count = 0;
- @Override
- public void run() {
- String name = Thread.currentThread().getName();
- if ("add".equalsIgnoreCase(name)) {
- addCount();
- } else {
- delCount();
- }
- }
- public void addCount() {
- synchronized (this) {
- for (int i = 0; i < 5; i++) {
- try {
- count = count + 1;
- System.out.println(Thread.currentThread().getName() + "[" + i + "]: " + count);
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public void delCount() {
- synchronized (this) {
- for (int i = 0; i < 5; i++) {
- try {
- count = count - 1;
- System.out.println(Thread.currentThread().getName() + "[" + i + "]: " + count);
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public static void main(String[] args) {
- SyncObjectTest objectTest = new SyncObjectTest();
- Thread thread = new Thread(objectTest, "add");
- Thread thread1 = new Thread(objectTest, "del");
- thread.start();
- thread1.start();
- }
- }
输出结果:
- add[0]: 1
- add[1]: 2
- add[2]: 3
- add[3]: 4
- add[4]: 5
- del[0]: 4
- del[1]: 3
- del[2]: 2
- del[3]: 1
- del[4]: 0
根据输出结果显示,说明在同一个对象实例中,synchronized修饰的所有方法不能并行执行
- public class SyncClassObject implements Runnable {
- private static int count = 0;
- @Override
- public void run() {
- method();
- }
- public synchronized static void method() {
- for (int i = 0; i < 5; i++) {
- count = count + 1;
- System.out.println(Thread.currentThread().getName() + "[" + i + "]: " + count);
- }
- }
- public static void main(String[] args) {
- SyncClassObject class1 = new SyncClassObject();
- SyncClassObject class2 = new SyncClassObject();
- Thread first = new Thread(class1, "first");
- Thread second = new Thread(class2, "second");
- first.start();
- second.start();
- }
- }
输出结果:
- first[0]: 1
- first[1]: 2
- first[2]: 3
- first[3]: 4
- first[4]: 5
- second[0]: 6
- second[1]: 7
- second[2]: 8
- second[3]: 9
- second[4]: 10
上述结果可知在类锁的情况下,即便创建了两个对象,类锁依然生效。
2.2 类锁写法二:修饰代码块、锁类对象
- public class SyncClassTest {
- public void test1() {
- synchronized (SyncClassTest.class) { //静态方法块类锁
- int i = 5;
- while (i-- > 0) {
- System.out.println(Thread.currentThread().getName() + ": " + i);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public static synchronized void test2() { //静态方法类锁
- int i = 5;
- while (i-- >0 ){
- System.out.println(Thread.currentThread().getName() + " : " + i);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void main(String[] args) {
- SyncClassTest syncClassTest = new SyncClassTest();
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- syncClassTest.test1();
- }
- });
- Thread thread1 = new Thread(new Runnable() {
- @Override
- public void run() {
- SyncClassTest.test2();
- }
- });
- thread.start();
- thread1.start();
- }
- }
输出结果:
- Thread-0: 4
- Thread-0: 3
- Thread-0: 2
- Thread-0: 1
- Thread-0: 0
- Thread-1 : 4
- Thread-1 : 3
- Thread-1 : 2
- Thread-1 : 1
- Thread-1 : 0
上述结果表示类锁已生效。
其实,类锁修饰方法和代码块的效果和对象锁是一样的,因为类锁只是一个抽象出来的概念,只是为了区别静态方法的特点,因为静态方法是所有对象实例共用的,所以对应着synchronized修饰的静态方法的锁也是唯一的,所以抽象出来个类锁。
- public class SyncClassTest {
- public synchronized void test1() { //类锁
- int i = 5;
- while (i-- > 0) {
- System.out.println(Thread.currentThread().getName() + ": " + i);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public static synchronized void test2() { //静态方法类锁
- int i = 5;
- while (i-- >0 ){
- System.out.println(Thread.currentThread().getName() + " : " + i);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void main(String[] args) {
- SyncClassTest syncClassTest = new SyncClassTest();
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- syncClassTest.test1();
- }
- });
- Thread thread1 = new Thread(new Runnable() {
- @Override
- public void run() {
- SyncClassTest.test2();
- }
- });
- thread.start();
- thread1.start();
- }
- }
输出结果:
- Thread-0: 4
- Thread-1 : 4
- Thread-1 : 3
- Thread-0: 3
- Thread-0: 2
- Thread-1 : 2
- Thread-1 : 1
- Thread-0: 1
- Thread-1 : 0
- Thread-0: 0
上面的synchronized
同时修饰静态方法和实例方法,结果交替运行,证明类锁和对象锁是两个不同的锁,控制不同的区域,互不干扰.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。