//错误典列
class A implements Runnable
{public static int tickets = 100;
public void run()
{
while(true)
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
public class TestTickets
{
public static void main(String[] args)
{
A aa1 = new A();
Thread t1 = new Thread(aa1);
t1.start();
A aa2 = new A();
Thread t2 = new Thread(aa2);
t2.start();
}
}
-------------------------------------------------------------------------------------
/* Synchronized关键字
-Synchronized可以用来修饰
---一个方法
---一个方法内部的某个代码块
*/
/*Synchronized修饰代码块
1.格式
synchronized(类对象名)//1行
{
同步代码块//3行
}//4行
2.功能
--synchronized(类对象名)的含义是:判断aa是否已经被其它线程霸占,如果发现已经被其它线程霸占,则当前线程陷入等待中,如果发现aa没有被其它线程霸占,则当前线程霸占住aa对象,并执行3行的同步代码,在当前线程执行3行代码时,其它线程将无法再执行3行的代码(因为当前线程已经霸占了aa对象),当前线程执行完3行代码后,会自动释放aa对象的霸占,此时其它线程会相互竞争对aa的霸占,最终CPU会选择其中的某一个线程执行
--最终导致的结果是:一个线程正在操作某资源的时候,将不允许其它线程操作该资源,即一次只允许一个线程处理该资源
*/
class A implements Runnable
{
public static int tickets = 100;
String str = new String("哈哈");
public void run()//还可以修饰方法public synchronized void run()
{
while(true)
{
synchronized (str)//多线程调用,普通方法调用无意义
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets2
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}
-------------------------------------------------------------------------
/*
创建线程的第一种方式 来买票
*/
class A extends Thread
{
public static int tickets = 100;
public static String str = new String("哈哈");//必须加上static,两个对象访问同一个synchronized
public void run()//还可以修饰方法public synchronized void run()
{
while(true)
{
synchronized (str)//多线程调用,普通方法调用无意义
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets3
{
public static void main(String[] args)
{
A aa1= new A();
aa1.start();
A aa2 = new A();
aa2.start();
}
}
-----------------------------------------------------------------------
//错误的程序
class A implements Runnable
{
public static int tickets = 100;
String str = new String("哈哈");
public synchronized void run()//void前面不能加synchronized否则会导致只有一个售票点在卖票
{
while(true)
{
// synchronized (str)//多线程调用,普通方法调用无意义
// {
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
// }
}
}
}
public class TestTickets4
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}
-----------------------------------------------------------------------
//错误的程序
class A implements Runnable
{
public static int tickets = 100;
String str = new String("哈哈");
public void run()
{
synchronized(str)
{
while(true)
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets5
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}
-------------------------------------------------------------------------
//错误的程序
class A implements Runnable
{
public static int tickets = 100;
public void run()
{
String str = new String("哈哈");//该语句执行两次。导致锁定的不是同一个str对象
while(true)
{
synchronized(str)
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets6
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}
--------------------------------------------------------------------
//错误的程序
class A implements Runnable
{
public static int tickets = 100;
String str = new String("哈哈");
public void run()
{
String str = new String("哈哈");
while(true)
{
synchronized(str)//与TestTickets6.java运行结果一样,因为在括号内写this.str
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets7
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}
-------------------------------------------------------------
//正确
class A implements Runnable
{
public static int tickets = 100;
String str1 = new String("哈哈");
public void run()
{
String str = "哈哈";//都指向同一字符串常量"哈哈"
while(true)
{
synchronized(str)
{
if(tickets > 0)
{
System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets8
{
public static void main(String[] args)
{
A aa= new A();
Thread t1 = new Thread(aa);
t1.start();
Thread t2 = new Thread(aa);
t2.start();
}
}