package multithreading;
引入bxdteachet的代码
/*
需求:卖票。
*/
/*
线程安全问题产生的原因:
1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。
就会导致线程安全问题的产生。
解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁(无效的判断)。
同步的前提:同步中必须有多个线程并使用同一个锁。
*/
class Ticket implements Runnable// extends Thread
{
private int num = 100;
Object obj = new Object();//成员变量时,与num一样,下面四个线程都共用同一个Object对象
public void run()// Runnable接口中的run()方法没有声明抛出异常,此处覆盖时也不能声明抛出异常 (只能catch不能声明的情况)
{
// Object obj = new Object();//每个线程开启后都有自己的run方法,每个run方法中都有局部变量Object obj对象,导致每个线程都有自己的锁,
// 所以不能同步了,所以不能Object对象不能放在这里
while (true) {
// synchronized (obj) {//传进来的obj叫同步锁或者对象锁
if (num > 0) {
try {
Thread.sleep(10);// void sleep(long millis)throws InterruptedException
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ".....sale...." + num--);
}
// }
}
}
}
class TicketDemo {
public static void main(String[] args) {
// implements Runnable后的代码
Ticket t = new Ticket();// 创建一个线程任务对象。
Thread t1 = new Thread(t);// 此处只有一个t传给线程对象
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();// 启动后t1、t2、t3、t4都在一起卖100张票
t2.start();
t3.start();
t4.start();
// extents Thread后的代码
// Ticket t1 = new Ticket();
// Ticket t2 = new Ticket();
// Ticket t3 = new Ticket();
// Ticket t4 = new Ticket();
// t1.start();
// t1.start();//一个线程不能开启两次,会抛出无效线程状态异常 IllegalThreadStateException - 如果线程已经启动。
// t1.start();
// t1.start();
// t1.start();//此处卖了400张票,t1、t2、t3、t4各卖100张票
// t2.start();
// t3.start();
// t4.start();
}
}