多线程弊端及解决办法

多线程的弊端

  • 共享数据错误

当多个线程共享数据,且共享区有两条以上代码时,线程切换可能发生在共享区,这时很容易引起数据错误

简单的比方就是本来是一批资源被多个人使用,本来应该是一个人使用结束后再下个人使用,但是现在每个人用一会儿,而且每个人都不知道这个资源还有别人使用,自己只能记录自己使用的情况,如果有个产品使用这个资源要三道工序,第一道供需完了后实际资源被给了其他人,那自己再次使用时记录的还是资源之前的状态,就会出现问题

  • 解决办法

用同步可以解决这个问题:提供“安全锁”,每次只让一个线程进入共享区,且进入前判断共享区标识,若空则进入,否则等待不能进入

同步的前提:
同步中必须有多个线程且必须使用同一个锁

  1. 方式一:同步代码块
    synchronized(对象)
    {
    需要同步的代码
    }
  2. 方式二:同步函数
    直接将函数加上synchronized

注意:同步函数使用的锁是this(当前对象)
(静态同步函数的锁:该函数所属字节码文件对象,可以用getClass方法获取,或是当前方法所属对象.getClass获取)

同步函数和同步代码块的区别

同步函数的锁是固定的this,后者的锁是任意的对象

虽然同步函数更为简洁,但是同步函数只是同步代码块的简写形式,功能体现更明显效率更高的是同步代码块

建议使用同步代码块,面试中也最为常见
eg:

class Ticket implements Runnable
{
    private int count = 100;
    Object obj = new Object();
    public void run()
    {
        //局部代码块封装可能出现线程安全的代码,然后同步
        synchronized(obj)
        {
        while(count>0)
        {
            try
            {
                Thread.sleep(10);
                task();
                //线程休眠10毫秒,sleep是静态方法,且抛出了InterruptedException异常,但是不能在run方法头上声明
                //因为接口Runnable没有声明异常,所以只能用try catch来捕捉异常
            }
            catch (InterruptedException ex)
            {
                //处理
            }   
        }
        }
    }
    void task()
    {
            System.out.println(Thread.currentThread().getName()+"count : "+count--);
    }
}
class ThreadSafe 
{
    public static void main(String[] args) 
    {
        Ticket  t = new Ticket();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        t1.start();
        t2.start();
        t3.start();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值