示例代码:
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;
/**
*
* Title: SaleTicket
*
* Description:
* 推荐:以后创建线程类建议通过实现接口的方式创建
* 原因:1.Java是单继承
* 2.语义好
*
* @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的方法 知识点的整理与总结的全部内容,另附源码
分割线
博主为咯学编程:父母不同意学编程,现已断绝关系;恋人不同意学编程,现已分手;亲戚不同意学编程,现已断绝来往;老板不同意学编程,现已失业三十年。。。。。。如果此博文有帮到你欢迎打赏,金额不限。。。