synchronized应该没问题吧,是没有共享num值?,但是设置了static还是没用?
public class ticketSell {
public static void main(String[] args) {
ticket ticket = new ticket();
ticket ticket1 = new ticket();
ticket ticket2 = new ticket();
ticket.start();
ticket1.start();
ticket2.start();
}
}
class ticket extends Thread {
public static int num = 100;
boolean loop = true;
@Override
public void run() {
while (loop) {
sell();
}
}
public synchronized void sell() {
if (num <= 0) {
loop = false;
System.out.println("售票结束");
return;
}
System.out.println(Thread.currentThread().getName() + "-窗口:卖出一张票,还剩:" + (--num));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
问题很明显,你的同步方法要是静态的,即public static synchronized修饰,因为你是用Thread创建多线程,此时,你创建了线程三个对象,如果你这个同步方法没有用static修饰,那么,这个同步锁就是this,你创建了三个对象,this不唯一,即同步锁不唯一,所以同步失败,加上static之后你的同步锁就是ticket.class,同步🔒唯一。
用Runnable创建多线程这不会出现这个情况!
多线程掌握不好,请看我这两篇博文:
http://t.csdn.cn/bNV50
http://t.csdn.cn/bMVqL
内含多线程总结以及不同多线程对卖票案例的实现。
有帮助的话采纳一下哦!
看看我举的这个例子,你就明白了
/**
* 线程同步之同步代码块和同步方法
* */
public class ThreadSynchronization {
public static void main(String[] args) {
Ticket2 ticket2=new Ticket2();
new Thread(ticket2,"窗口1").start();
new Thread(ticket2,"窗口2").start();
new Thread(ticket2,"窗口3").start();
new Thread(ticket2,"窗口4").start();
}
}
/**Ticket1类实现Runnable接口*/
class Ticket1 implements Runnable{
private int tickets=10;
//定义任意一个对象,用作同步代码块的锁
Object lock=new Object();
@Override
public void run() {
while(true){
/**定义同步代码块*/
synchronized (lock){
try{Thread.sleep(10);}
catch (InterruptedException e)
{e.printStackTrace();}
if(tickets>0) {
//获取当前线程
Thread th = Thread.currentThread();
//获取当前线程的名字
String th_name = th.getName();
System.out.println(th_name + "正在发售第" + tickets-- + "张票");
}else{break;}//如果tickets小于0,跳出循环
}
}
}
}
/**Ticket2类实现Runnable接口*/
class Ticket2 implements Runnable{
private int tickets=10;
public void run() {
while(true){
//调用售票方法
saleTicket();
if(tickets<=0){break;}
}
}
//定义一个同步方法saleTicket(),锁的是this
private synchronized void saleTicket(){
if(tickets>0)
{
try{Thread.sleep(10);}//经过此处线程休眠10毫秒
catch (InterruptedException e){e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"---卖出的票号"+tickets--);
}
}
}
同步方法实现的:
不知道你解决了没有?我这也添加点见解。
你目前的情况是不理解synchronized和static的作用域,
如果你理解了,或许你会更清楚。
1、样例代码,前面回答有了;
2、理论,前面也有了;
3、可能你不理解,你看看是否需要有人手把手说明。