多线程同步几个例子(买票程序的synchronized)

来源:互联网 发布:linux 修改可见密码 编辑:程序博客网 时间:2024/05/16 15:29

//例子1:用extends继承Thread类,使用synchronized修饰方法里面代码块的办法

//这里面的记得static是必须的,因为如果不用static的话 在Test类中声明了两个A的对象,各自都有自己的100张票
//违背了火车站点购票资源统一的原则


class A extends Thread{
   public static String str = new String("haha");    //static 不能省啊
   public static int tickets = 100;  //static 不能省啊


   public synchronized void run(){
         synchronized(str){
     while(tickets>0){
  System.out.printf("%s正在卖第%d张票\n",Thread.currentThread().getName(),tickets);
  tickets--;
     }
   }
   }
}

public class Test {
public static void main(String [] args)
{
       A aa1 = new A();
       aa1.start();
       
       A aa2 = new A();
       aa2.start();
}
}  

//例子2:用extends实现Runnable接口,使用synchronized修饰方法里面代码块的办法
//这里面的我们不需要写static,因为可以用A的对象aa定义两个线程,但是两个线程公用一个aa对象的资源
class A implements Runnable{
   public String str = new String("haha");  
   public int tickets = 100;


   public synchronized void run(){
      synchronized(str){
     while(tickets>0){
  System.out.printf("%s正在卖第%d张票\n",Thread.currentThread().getName(),tickets);
  tickets--;
     }
  }
   }
}


public class Test {
public static void main(String [] args){
       A aa = new A();
       Thread t1 = new Thread(aa);
       t1.start();
       
       Thread t2 = new Thread(aa);
       t2.start();   
}
}  




//例子3:synchronized写在方法前面的话(而不是方法的代码端上),只有一个站点(线程)执行卖票
//下面的程序只有一个线程被输出


class A implements Runnable{
   public String str = new String("haha");  
   public int tickets = 100;


   public synchronized void run(){ //
        // synchronized(str){
     while(tickets>0){
  System.out.printf("%s正在卖第%d张票\n",Thread.currentThread().getName(),tickets);
  tickets--;
     //}
  }
   }
}


public class Test {
public static void main(String [] args){
       A aa = new A();
       Thread t1 = new Thread(aa);
       t1.start();
       
       Thread t2 = new Thread(aa);
       t2.start();   
}
}  




总结: synchronized 修饰一个方法时,实际霸占的是该方法的this指针所指向的对象
       即:synchronized 修饰一个方法时,实际霸占的正在调用该方法的对象,只用该对象释放的时候,其他对象才能调用该方法
       
 ps:霸占的专业俗语叫锁定,霸占住的那个对象专业俗语叫做监听器  霸占只允许一个霸占
 
 
      
       

补充知识
String 和 new String 的区别
public class Test {
public static void main(String [] args)
{
String aa1 = "哈哈"; //此时的“哈哈”是在数据区,故aa1和aa2是相等的     创建了一个对象
String aa2 = "哈哈"; //这种方式会创建一个对象            创建了一个对象
String aa3 = new String("哈哈");//“哈哈”在堆区存放   这句创建了两个对象

System.out.println(aa1==aa2);//true
System.out.println(aa1==aa3);   //false
System.out.println(aa2==aa3);   //false
System.out.println(aa1.equals(aa3));//true
System.out.println(aa3.equals(aa2));//true
}
}  
0 0
原创粉丝点击