Java-线程的bug及三种解决bug的方法

涎涎原创约 755 字大约 3 分钟...JavaJava

150-Java-线程的bug及三种解决bug的方法.mdopen in new window

注意

本博文仅供学术研究和交流参考,严禁将其用于商业用途。如因违规使用产生的任何法律问题,使用者需自行负责。

示例代码:

package 线程的bug;

public class Ticket {

	private int count = 1000;
	
	//会产生bug
	public void saleTicket() {
		if(count > 0) {
			System.out.println(Thread.currentThread().getName() + ": " + count);
			count--;
		}
	}
}
package 线程的bug;
/**
 * 
* <p>Title: SaleTicket</p>  
* <p>
* 	Description: 
*  推荐:以后创建线程类建议通过实现接口的方式创建
*  原因:1.Java是单继承
*  		 2.语义好
* </p>  
* @author xianxian 
* @date 2019年7月17日
 */
public class SaleTicket implements Runnable{

	private Ticket ticket;
	
	public SaleTicket(Ticket ticket) {
		this.ticket = ticket;
	}
//	private int startNumber;
//	private int endNumber;
//	
//	public  SaleTicket(int startNumber,int endNumber) {
//		this.startNumber = startNumber;
//		this.endNumber = endNumber;
//	}
	
	
//	@Override
//	public void run() {
//		for (int i = this.startNumber; i <= this.endNumber; i++) {
//			System.out.println(Thread.currentThread().getName() + ": " + i);
//		}
//	}
	
	@Override
	public void run() {
		for (int i = 1; i <= 1000; i++) {
			System.out.println(Thread.currentThread().getName() + ": " + i);
		}
	}
}
package 线程的bug;

public class Test {

	public static void main(String[] args) {
		
		Ticket t = new Ticket();
		/**
		 * 出现bug:卖了三张同样的票
		 * 1、三个线程操作的是同一个对象
		 * 2、三个 线程访问的count是同一个
		 * 对象的属性,然后代码执行过程中
		 * 时间片随时会被抢走,所以代码
		 * 会出问题
		 */
		SaleTicket s1 = new SaleTicket(t);
		new Thread(s1).start();
		SaleTicket s2 = new SaleTicket(t);
		new Thread(s2).start();
		SaleTicket s3 = new SaleTicket(t);
		new Thread(s3).start();

//		SaleTicket s1 = new SaleTicket(1, 100);
//		new Thread(s1).start();
//		SaleTicket s2 = new SaleTicket(101, 200);
//		new Thread(s2).start();
//		SaleTicket s3 = new SaleTicket(201, 300);
//		new Thread(s3).start();
		
		
		
		/*
	 	@Override
	public void run() {
		for (int i = 1; i <= 100; i++) {
			if(count>0)
		{
			System.out.println(Thread.currentThread().getName()+":"+count);
			count--;
		}
		}
	}
	 
	 */
	}
}

测试结果如图所示,线程bug:1000数字现现咯三次,显然不是我们的期望。

解决bug的方法一给方法上锁

package 线程的bug;

public class Ticket {

	private int count = 1000;
	
    public synchronized void saleTicket() {//解决bug方法一:上锁 加关键字synchronized
        if(count > 0) {
            System.out.println(Thread.currentThread().getName() + ": " + count);
            count--;
        }
    }
}

解决bug的方法二锁共享对象

package 线程的bug;

public class Ticket {

	private int count = 1000;
	
	public void saleTicket() {
		synchronized (this) {//解决bug方法二:锁住共享对象
			if(count > 0) {
				System.out.println(Thread.currentThread().getName() + ": " + count);
				count--;
			}
		}
	}
}

解决bug的方法三是用Lock对象

package 线程的bug;

import java.util.concurrent.locks.Lock;//解决bug方法三:使用Lock对象
import java.util.concurrent.locks.ReentrantLock;//解决bug方法三:使用Lock对象

public class Ticket {

	private int count = 1000;
	
	private Lock lock = new ReentrantLock();//解决bug方法三:使用Lock对象
	
	
	public void saleTicket() {//解决bug方法三:使用Lock对象
		lock.lock();//上锁
		if(count > 0) {
			System.out.println(Thread.currentThread().getName() + ": " + count);
			count--;
		}
		lock.unlock();//解锁
	}
}

以上三种方法测试运行结果如下图所示,已解决咯上述问题:


分割线


相关信息

以上就是我关于 Java-线程的bug及三种解决bug的方法 知识点的整理与总结的全部内容,另附源码open in new window

上次编辑于:
贡献者: 涎涎
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.4