A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 戴振良 黑马帝   /  2012-12-3 13:53  /  1120 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 戴振良 于 2012-12-3 14:42 编辑

静态方法与非静态方法之间的同步
class Q {
   public static synchronized void function1(){}
   public synchronized void function2(){}
}
此处方法1和方法2不是同步的,因为方法1使用的同步对象是: Q.class ,而方法2使用的同步对象是: this ,要想这两个方法之间实例同步,只要使用相同的同步对象即可,如:
class Q {
   public static synchronized void function1(){}
   public void function2(){
      synchronized (Q.class) {

      }
   }
}
思想:把需要使用相同数据的方法(或者说有关联的两个方法或多个方法)写到一个类中,使用到的数据也放到那个类中,这种写法很方便管理和省事,而且写起来代码更少,这也是面向对象的思想

使用synchronized代码块或同步方法,这叫互相排斥,即A线程执行了这块代码,B线程就不能执行了,B线程执行了,A线程就不能执行,这只是保证了代码块或方法同一时间只能被一个线程执行,然而代码块或方法有可能被线程A连续执行3次才到线程B执行1次。有时候需要A执行1次,B执行一次,然后A执行一次,B执行一次,如此反复执行,这叫同步,实现种这需求的实例如下:
代码同步的例子:
需求:
有两个线程,先让主线程的方法循环2次,再让子线程的方法循环3次,如此反复执行4
代码运行效果如下:
main 1
main 2
sub 1
sub 2
sub 3
---------------------1-----------------
main 1
main 2
sub 1
sub 2
sub 3
---------------------2-----------------
main 1
main 2
sub 1
sub 2
sub 3
---------------------3-----------------
main 1
main 2
sub 1
sub 2
sub 3
---------------------4-----------------

实现同步的代码如下:
package com.itheima.threadtest;

public class A {

   public static void main(String[] args) {
      new Thread(){public void run(){   //开一个子线程
         for(int i=1;i<=4;i++) B.f2();   //在子线程中执行f2方法4次
      }}.start();

      for(int i=1;i<=4;i++) B.f1();     //在主线程中执行f1方法4次
   }
}

class B {
   public static boolean runF1 = true;  //默认先运行f1方法,true为运行,false为不运行
   public static synchronized void f1(){
      if(!runF1) try {B.class.wait();} catch (InterruptedException e) {e.printStackTrace();} //如果不是运行f1方法,让当前线程等待,否则执行循环2次
      for(int i=1; i<=2; i++) System.out.println("main " + i);
      runF1 = false;
      B.class.notify();
   }

   public static synchronized void f2(){
      if(runF1) try {B.class.wait();} catch (InterruptedException e) {e.printStackTrace();} //如果是运行f1方法,让当前线程等待,否则执行循环3次
      for(int i=1; i<=3; i++) System.out.println("sub " + i);
      System.out.println("------------------"+ i +"--------------------");
      runF1 = true;
      B.class.notify();
   }
}
声明:我知道我代码写的不规范,请大家不要批评我,不知道为什么我就是喜欢这样写,看着代码少我就爽。
疑惑:
不管B.runF1 变量设为truefalse (f1方法先运行或让f2方法先运行),都不能改变main方法中红色代码蓝色代码的顺序,否则会变成死锁,又或者不是死锁,总之效果是没有任何输出,卡住。
也许你会认为是我用了静态方法的原因,但是我试过删除静态,一样没变。
我的电脑是8线程的,我不知道这是否与电脑CPU有关,请大家运行测试,试试看,你也会写同步代码了哦!

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马