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

示例代码:

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数字现现咯三次,显然不是我们的期望。

Java-线程的bug及三种解决bug的方法_第1张图片

解决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的方法_第2张图片

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


分割线


博主为咯学编程:父母不同意学编程,现已断绝关系;恋人不同意学编程,现已分手;亲戚不同意学编程,现已断绝来往;老板不同意学编程,现已失业三十年。。。。。。如果此博文有帮到你欢迎打赏,金额不限。。。

你可能感兴趣的:(Java-线程的bug及三种解决bug的方法)