java 小程序 多线程_对于JAVA多线程卖票小程序的理解

昨天把多线程重新看了一遍,发现自己还是有许多需要理解的地方,现在写一篇总结。

一:利用继承Thread类会出现的问题:

public class SellTicketsThread extends Thread {

private int tickets = 10;

public SellTicketsThread(String name) {

super(name);

}

@Override

public void run() {

while (true) {

if(tickets<=0) break;

synchronized (this) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if (tickets > 0) {

System.out.println(Thread.currentThread().getName() + "卖出第"

+ tickets-- + "张票");

}

}

}

}

}

public class SellTicketsThreadDemo {

public static void main(String[] args) {

SellTicketsThread t1 = new SellTicketsThread("窗口1");

SellTicketsThread t2 = new SellTicketsThread("窗口2");

SellTicketsThread t3 = new SellTicketsThread("窗口3");

t1.start();

t2.start();

t3.start();

}

}

这样的话看上去是用了同步锁锁住了对象,但运行结果却是不符合逻辑的。三个窗口共卖了30张票。

窗口2卖出第10张票

窗口1卖出第10张票

窗口3卖出第10张票

窗口3卖出第9张票

窗口2卖出第9张票

窗口1卖出第9张票

窗口3卖出第8张票

窗口1卖出第8张票

窗口2卖出第8张票

窗口2卖出第7张票

窗口3卖出第7张票

窗口1卖出第7张票

窗口2卖出第6张票

窗口1卖出第6张票

窗口3卖出第6张票

窗口2卖出第5张票

窗口1卖出第5张票

窗口3卖出第5张票

窗口2卖出第4张票

窗口3卖出第4张票

窗口1卖出第4张票

窗口2卖出第3张票

窗口1卖出第3张票

窗口3卖出第3张票

窗口2卖出第2张票

窗口1卖出第2张票

窗口3卖出第2张票

窗口2卖出第1张票

窗口3卖出第1张票

窗口1卖出第1张票

二:利用Runnale接口实现

package SellTickets;

public class SellTicketsThread implements Runnable{

private int tickets = 10;

@Override

public void run() {

while(true){

if(tickets<=0) break;

synchronized(this){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(tickets>0){

System.out.println(Thread.currentThread().getName()+"卖出第"+tickets--+"张票");

}

}

}

}

}

public class SellTicketsThreadDemo {

public static void main(String[] args) {

SellTicketsThread st = new SellTicketsThread();

Thread t1 = new Thread(st,"窗口一");

Thread t2 = new Thread(st,"窗口二");

Thread t3 = new Thread(st,"窗口三");

t1.start();

t2.start();

t3.start();

}

}

窗口一卖出第10张票

窗口一卖出第9张票

窗口一卖出第8张票

窗口三卖出第7张票

窗口二卖出第6张票

窗口二卖出第5张票

窗口三卖出第4张票

窗口三卖出第3张票

窗口三卖出第2张票

窗口三卖出第1张票

这样就不会有问题了,因为三个线程共享的是同一个Runnable开辟的内存.网上几乎都是用的这种方法,能不能不用Runnable接口也能实现这个效果呢??接下来是用Thread实现的两种方式,如有错误之处还请指正.

三:在继承Thread的类中定义静态变量和静态方法,将锁加在静态方法上,让多个线程共享。

public class SellTicketsThread extends Thread {

public SellTicketsThread(String name){

super(name);

}

public SellTicketsThread(){

}

private static int tickets =10;

public synchronized static void take(){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(tickets>0){

System.out.println(Thread.currentThread().getName() + "卖出第"

+ tickets-- + "张票");

}

}

@Override

public void run() {

while(true){

take();

}

}

}

public class SellTicketsThreadDemo {

public static void main(String[] args) {

SellTicketsThread t1 = new SellTicketsThread("窗口1");

SellTicketsThread t2 = new SellTicketsThread("窗口2");

SellTicketsThread t3 = new SellTicketsThread("窗口3");

t1.start();

t2.start();

t3.start();

}

}

窗口1卖出第10张票

窗口1卖出第9张票

窗口3卖出第8张票

窗口3卖出第7张票

窗口3卖出第6张票

窗口2卖出第5张票

窗口2卖出第4张票

窗口3卖出第3张票

窗口1卖出第2张票

窗口1卖出第1张票

四:定义一个锁对象,让多个线程共同用同一个锁,同时将共享变量定义成静态的。

public class SellTicketsThread extends Thread {

Object o =null;

private static int tickets = 10;

public SellTicketsThread(String name,Object o){

super(name);

this.o = o;

}

public SellTicketsThread(){

}

@Override

public void run() {

while(true){

while(true){

if(tickets<=0) break;

synchronized(o){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(tickets>0){

System.out.println(Thread.currentThread().getName()+"卖出第"+tickets--+"张票");

}

}

}

}

}

}

public class SellTicketsThreadDemo {

public static void main(String[] args) {

Object o = new Object();//共同的锁

SellTicketsThread t1 = new SellTicketsThread("窗口1",o);

SellTicketsThread t2 = new SellTicketsThread("窗口2",o);

SellTicketsThread t3 = new SellTicketsThread("窗口3",o);

t1.start();

t2.start();

t3.start();

}

}

窗口1卖出第10张票

窗口1卖出第9张票

窗口1卖出第8张票

窗口3卖出第7张票

窗口3卖出第6张票

窗口3卖出第5张票

窗口3卖出第4张票

窗口2卖出第3张票

窗口2卖出第2张票

窗口2卖出第1张票

还需要注意的是,同步代码块的锁对象是任意对象。所以可以用Object做为一个锁。而同步方法(非静态)的锁对象是 this。静态方法的锁对象是类的字节码文件对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值