温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java 多线程-改正不安全线程

发布时间:2020-08-05 19:21:42 来源:网络 阅读:226 作者:wx5d21d5e6e5ab1 栏目:编程语言

并发:
同一个对象对多个线程同时操作
线程同步:一种等待机制,等待前面线程使用完再下一个线程使用
线程同步形成条件:形成队列,加上锁机制(synchronized)
同步块:synchronized(具体对象){代码};锁定资源,一个线程一个线程的使用

抢票:

public class n {

public static void main(String[]args) throws InterruptedException
{
web wb=new web();
new Thread(wb,"a").start();
new Thread(wb,"b").start();
new Thread(wb,"c").start();
}
}

class web implements Runnable{
int num=10;
private boolean flag=true;
public void run()
{
while(flag)
{
    test();
}
}
public synchronized void test()//锁的是对象的资源,即this成员,让资源每次只被一个线程使用,然后下次靠cpu调度,而不让
                            //一份资源同时被多个线程使用
{   if(num<0)
        {
    flag=false;
    return;
}
try {
    Thread.sleep(200);
}catch(InterruptedException e)
{
    e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+num--);
//线程不安全,可能都都是同一张票,可能票是负数
//负数:当还有1张票时,三个线程同时进入,都等待后,有两个线程为负数
//相同票:线程有自己的工作台,多个线程几乎同时到达,拷贝数据
}
}

取钱:

public class el {

public static void main(String[]args)
{
    account a=new account(100,"me");
    get g=new get(a,80,"she");
    get g2=new get(a,90,"he");
    g.start();
    g2.start();
}

}

//账户
class account {
int money;
String name;
public account(int money,String name)
{
    this.money=money;
    this.name=name;
}

}
//模拟取款

class get extends Thread
{
account a; //取钱的账户
int getmoney; //单个人取的钱数
int getall; //多个人取的总数

public get (account a,int getmoney,String name)
{
    super(name);//Thread可以设置name
    this.a=a;
    this.getmoney=getmoney;
}

public void run()
{
    test();
}
public /*synchronized */void test()//锁定失败,不应该锁this,而应该锁account
{//因为a.money是account里的,总钱数应该每次由一个线程调用,而不是多个线程
//使用同步块锁定
    if(a.money<=0)
    {
        return;
    }
synchronized(a){

    if(a.money-getmoney<0) //添加也没用
    {
        return;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    a.money-=getmoney;
    getall+=getmoney;
    System.out.println(this.getName()+"-->账户余额为:"+a.money);
    System.out.println(this.getName()+"-->取钱总数为:"+getall);
}
}
}

容器:

public class h {

public static void main(String[]args)
{
    List<String> list=new ArrayList<String>();

    for(int i=0;i<10000;i++)
    {
        new Thread(()->
        {synchronized(list) {
            list.add(Thread.currentThread().getName());}}
                ).start();
    }
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(list.size());

}
}
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI