//例子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
}
}