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

来源:互联网 发布:spine导入到unity3d 编辑:程序博客网 时间:2024/05/16 08:03
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;}@Overridepublic  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 

从第二段代码可知,同步的关键是多个线程对象竞争同一个共享资源即可,上面的代码中是通过外部创建共享资源,然后传递到线程中来实现。我们也可以利用类成员变量被所有类的实例所共享这一特性,因此可以将
lock用静态成员对象来实现,代码如下所示:修改MyThread.java类如下

package com.clark.thread;public class MyThread implements Runnable{private int threadId;private static Object object = new Object();//线程之间竞争使用的对象锁public MyThread(int id){this.threadId = id;}@Overridepublic  void run() {<strong>/** * 将这个object对象的引用传递给每一个线程对象的lock成员变量 * 从而每个线程的lock成员都指向同一个Object对象 * 这样就可以让线程去竞争这个唯一的共享的对象锁,从而实现同步。 */</strong>synchronized(object){for (int i = 0; i < 100; i++) {if(i % 10 ==0){System.out.println();}System.out.print("Thread ID:"+this.threadId+":"+i+" ");}}}}
结果如下:
Thread ID:0:0 Thread ID:0:1 Thread ID:0:2 Thread ID:0:3 Thread ID:0:4 Thread ID:0:5 Thread ID:0:6 Thread ID:0:7 Thread ID:0:8 Thread ID:0:9 Thread ID:0:10 Thread ID:0:11 Thread ID:0:12 Thread ID:0:13 Thread ID:0:14 Thread ID:0:15 Thread ID:0:16 Thread ID:0:17 Thread ID:0:18 Thread ID:0:19 Thread ID:0:20 Thread ID:0:21 Thread ID:0:22 Thread ID:0:23 Thread ID:0:24 Thread ID:0:25 Thread ID:0:26 Thread ID:0:27 Thread ID:0:28 Thread ID:0:29 Thread ID:0:30 Thread ID:0:31 Thread ID:0:32 Thread ID:0:33 Thread ID:0:34 Thread ID:0:35 Thread ID:0:36 Thread ID:0:37 Thread ID:0:38 Thread ID:0:39 

再来看第一段代码,实例方法中加入sychronized关键字封锁的是this对象本身,而在静态方法中加入sychronized关键字封锁的就是类本身。静态方法是所有类实例对象所共享的,因此线程对象在访问此静态方法时是互斥访问的,从而可以实现线程的同步,代码如下所示:

package com.clark.thread;public class MyThread implements Runnable{private int threadId;public MyThread(int id){this.threadId = id;}@Overridepublic  void run() {start(this.threadId);}private static synchronized void start(int threadId2) {for (int i = 0; i < 100; i++) {if(i % 10 == 0){System.out.println();}System.out.print("Thread ID:"+threadId2+":"+i+" ");}}}

结果如下=========

Thread ID:0:0 Thread ID:0:1 Thread ID:0:2 Thread ID:0:3 Thread ID:0:4 Thread ID:0:5 Thread ID:0:6 Thread ID:0:7 Thread ID:0:8 Thread ID:0:9 Thread ID:0:10 Thread ID:0:11 Thread ID:0:12 Thread ID:0:13 Thread ID:0:14 Thread ID:0:15 Thread ID:0:16 Thread ID:0:17 Thread ID:0:18 Thread ID:0:19 Thread ID:0:20 Thread ID:0:21 Thread ID:0:22 Thread ID:0:23 Thread ID:0:24 Thread ID:0:25 Thread ID:0:26 Thread ID:0:27 Thread ID:0:28 Thread ID:0:29 Thread ID:0:30 Thread ID:0:31 Thread ID:0:32 Thread ID:0:33 Thread ID:0:34 Thread ID:0:35 Thread ID:0:36 Thread ID:0:37 Thread ID:0:38 Thread ID:0:39 Thread ID:0:40 Thread ID:0:41 Thread ID:0:42 Thread ID:0:43 Thread ID:0:44 Thread ID:0:45 Thread ID:0:46 Thread ID:0:47 Thread ID:0:48 Thread ID:0:49 Thread ID:0:50 Thread ID:0:51 Thread ID:0:52 Thread ID:0:53 Thread ID:0:54 Thread ID:0:55 Thread ID:0:56 Thread ID:0:57 Thread ID:0:58 Thread ID:0:59








1 1
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子把褥子尿湿怎么办 小孩尿过的褥子怎么办 包包放着发霉了怎么办 被套盖久了发黄怎么办 小白鞋里面发霉怎么办 棉被淋了一点雨怎么办 苹果手机被拉进电话群怎么办 墙上的插座烧了怎么办 富士康早退4分钟怎么办 我老婆起泡疹腿剌痛睡不着了怎么办 oppo耳机孔坏了怎么办 魅族耳机口坏了怎么办 控制线的报验资料怎么办 人失踪报警派出所不管怎么办 铁板的货架久了怎么办 干镀锌让环保查了怎么办 水管软管生锈了拧不动怎么办 镀锌管会生锈吗.怎么办 冷镀锌钢管生锈了怎么办 卖了过期的东西怎么办 喝到了假的饮料怎么办 烧汤总是溢锅怎么办 脚踩垃圾桶坏了怎么办 连衣裙特别容易起褶怎么办 施肥过度烧根了怎么办 农作物施用尿素发生肥害怎么办? 水稻尿素施多了怎么办 花施肥施多了怎么办 玉米被化肥烧了怎么办 撒施复合肥没有充分融化怎么办 绿箩化肥施多了怎么办 辣椒化肥施多了怎么办? 化肥施多了烧苗怎么办 绿植施肥施多了怎么办 盆栽肥料放多了怎么办 三环复合肥怎么办啊 母猪下崽后不吃食怎么办 猪自配料料槽不下怎么办 美甲边缘起翘怎么办 猪粪流到鱼塘里鱼死了怎么办啊 在基本农田建有机肥厂怎么办