问题原因:线程1还未执行完操作,后面线程却接种而来
解决:必须保证一个线程a在操作ticket时,其它线程等待,直到a操作完成,其它线程才能继续操作
方式1:同步代码块:synchornized(同步监视器(锁)){一般使用this
//共享代码}其它线程得等待
同步监视器可以 用任何一个类充当,但是多个线程必须共同使用一个监视器
关于多线程同时进行对某变量的同时操作时产生的安全问题
例如三个窗口共卖100张票,不可重复卖票,意即三个窗口共享一个票,采用接口实现类创建多线程
public class WindowTest {
public static void main(String[] args) {
//创建三个线程
Ticket t= new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
//分别给三个线程命名
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
//但以上结果出现了3次100的票,采用继承方式也会存在安全问题(if语句)
}
}
class Ticket implements Runnable{
int ticket=100;
Object obj =new Object();
@Override
public void run() {
//int ticket = 100;如果定义在方法内部则会导致每一份对象都会有100张票
while(true)//如果synchronized把while也包住了就不是多线程了
{
try {
Thread.sleep(5);//加点延迟不然不行
} catch (InterruptedException e) {
e.printStackTrace();
}
//synchronized (obj){//obj是唯一的
synchronized (this){//或者Ticket.class
//继承中的this不唯一
// this是唯一的,在接口实现类下,因为this是指调用run方法的对象也就只是Ticket t= new Ticket();
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+":"+"第"+ticket+"张票售出");
ticket--;
}
else
break;
}
}
}
}
-----------------------------------------下面是继承类的多线程解决-------------------------------------------
/*
* 采用继承类实现多线程
* 使用同步代码快解决安全问题synchronized
* 同步监视器慎用this关键看对象是否唯一
*
* */
public class window {
public static void main(String[] args) {
windows w1= new windows();
windows w2= new windows();
windows w3= new windows();
w1.setName("窗口1");
w2.setName("窗口2");
w3.setName("窗口3");
w1.start();
w2.start();
w3.start();
}
}
class windows extends Thread{
static int ticket=100;
//static Object obj = new Object();//方式一
public void run()
{
while(true)
{
//synchronized (this){//此处this 指w1,w2,w3
//synchronized (obj){//使用obj静态
synchronized (Window.class){//要放对象 Class clz = Window.class
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+":"+"第"+ticket+"张票售出");
ticket--;
}
else
break;
}
}
}
}