Java中利用synchronized关键字实现多线程同步问题

Java 中多线程的同步依靠的是对象锁机制,synchronized关键字就是利用了封装对象锁来实现对共享资源的互斥访问。

下面以一个简单例子来说明多线程同步问题,我们希望在run()方法里加入synchronized关键字来实现互斥访问。

package com.clark.thread;

public class MyThread implements Runnable{
    private int threadId;
   
    public MyThread(int id){
        this.threadId = id;
    }
    @Override
    public synchronized void run() {
        //此时关键字synchronized锁住的是this对象,即当前运行线程对象本身
        for (int i = 0; i < 100; i++) {
            if(i % 10 ==0){
                System.out.println();
            }
            System.out.print("Thread ID:"+this.threadId+":"+i+" ");
        }
    }

}

测试类:

package com.clark.thread;

public class ThreadDemo {
 public static void main(String[] args) throws InterruptedException {
                //代码中创建了10个线程,而每个线程都持有this对象的对象锁,这不能实现线程的同步。
                for (int i = 0; i < 10; i++) {
   new Thread(new MyThread(i)).start();
   Thread.sleep(1);
  }
 }
}

打印结果部分如下:其线程不是互斥访问的。因此没有达到资源多线程同步效果。。。

Thread ID:1:60 Thread ID:1:61 Thread ID:1:62 Thread ID:1:63 Thread ID:1:64 Thread ID:1:65 Thread ID:1:66 Thread ID:1:67 Thread ID:1:68 Thread ID:1:69
Thread ID:1:70 Thread ID:1:71 Thread ID:1:72 Thread ID:1:73 Thread ID:1:74 Thread ID:1:75 Thread ID:1:76
Thread ID:1:77 Thread ID:1:78 Thread ID:1:79
Thread ID:1:80 Thread ID:1:81 Thread ID:2:0 Thread ID:1:82 Thread ID:1:83 Thread ID:1:84 Thread ID:1:85 Thread ID:1:86 Thread ID:1:87 Thread ID:1:88 Thread ID:1:89
Thread ID:1:90 Thread ID:1:91 Thread ID:1:92 Thread ID:1:93 Thread ID:1:94 Thread ID:1:95 Thread ID:2:1 Thread ID:2:2 Thread ID:2:3 Thread ID:2:4 Thread ID:2:5 Thread ID:2:6 Thread ID:2:7 Thread ID:2:8 Thread ID:2:9

从上述得知,要想实现线程同步,必须让这些线程去竞争一个唯一的共享对象锁。

package com.clark.thread;

public class MyThread implements Runnable{
 private int threadId;
 private Object object;//线程之间竞争使用的对象锁
 public MyThread(int id,Object object){
  this.threadId = id;
  this.object = object;
 }
 @Override
 public  void run() {
  /**
  * 将这个object对象的引用传递给每一个线程对象的lock成员变量
  * 从而每个线程的lock成员都指向同一个Object对象
  * 这样就可以让线程去竞争这个唯一的共享的对象锁,从而实现同步。
  */
  synchronized(object){
   for (int i = 0; i < 100; i++) {
    if(i % 10 ==0){
     System.out.println();
    }
    System.out.print("Thread ID:"+this.threadId+":"+i+" ");
   }
  }
 }

}

package com.clark.thread;

public class ThreadDemo {
 public static void main(String[] args) throws InterruptedException {
  Object obj = new Object();
  for (int i = 0; i < 10; i++) {
   new Thread(new MyThread(i,obj)).start();
   Thread.sleep(1);
  }
 }
}

测试结果如下:

Thread ID:5:60 Thread ID:5:61 Thread ID:5:62 Thread ID:5:63 Thread ID:5:64 Thread ID:5:65 Thread ID:5:66 Thread ID:5:67 Thread ID:5:68 Thread ID:5:69
Thread ID:5:70 Thread ID:5:71 Thread ID:5:72 Thread ID:5:73 Thread ID:5:74 Thread ID:5:75 Thread ID:5:76 Thread ID:5:77 Thread ID:5:78 Thread ID:5:79
Thread ID:5:80 Thread ID:5:81 Thread ID:5:82 Thread ID:5:83 Thread ID:5:84 Thread ID:5:85 Thread ID:5:86 Thread ID:5:87 Thread ID:5:88 Thread ID:5:89
Thread ID:5:90 Thread ID:5:91 Thread ID:5:92 Thread ID:5:93 Thread ID:5:94 Thread ID:5:95 Thread ID:5:96 Thread ID:5:97 Thread ID:5:98 Thread ID:5:99
Thread ID:6:0 Thread ID:6:1 Thread ID:6:2 Thread ID:6:3 Thread ID:6:4 Thread ID:6:5 Thread ID:6:6 Thread ID:6:7 Thread ID:6:8 Thread ID:6:9
Thread ID:6:10 Thread ID:6:11 Thread ID:6:12 Thread ID:6:13 Thread ID:6:14 Thread ID:6:15 Thread ID:6:16 Thread ID:6:17 Thread ID:6:18 Thread ID:6:19
Thread ID:6:20 Thread ID:6:21 Thread ID:6:22 Thread ID:6:23 Thread ID:6:24 Thread ID:6:25 Thread ID:6:26 Thread ID:6:27 Thread ID:6:28 Thread ID:6:29

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/fecea48ca269f7c248f280afa2c0f3b1.html