多线程同步方法以及线程安全

线程实现的方式
1、extents thread
2、implememts runnable 

由于多线程是异步的,所有会产生线程安全问题。

线程安全:就是多线程访问时,加同步锁,当一个线程访问该类的成员变量【类中方法外】,其他线程不能进行行访问直到该线程读取完,其他线程才可使用,也就是不会出现数据不一致或者数据污染。
相对来说就是线程不安全:不提供数据访问保护,导致的多个线程对同一对象中的变量进行并发访问时产生的脏数据,

由上面引起:多线程下对类的成员变量的读写操作引起的。

成员变量分为:
静态属性【类变量,static修饰】:随类的存在而存在,是在类加载的初始化
非静态属性【类的实例变量】:随实例的属性存在而存在。

局部变量:
局部变量不能加static,包括protected, private, public这些也不能加。局部变量保存在栈中。
局部编程必须在声明时初始化。

非线程安全的解决方法是什么???
    1、把对象设置成不带属性。将对象设置成无状态的,不带属性就不存在多线程对变量的读取、修改。
    2、设置成局部变量(方法内的变量,不是类变量)?为啥?多线程调用同一个对象的方式时,方法内的对象是私有的
    3、用ThreadLocal,为每个线程都创建一个对象。
    4、同步方法:加同步锁[互斥锁],按照顺序排队访问 synthronized、lock
       例如:synthronized public void run(){}


1、方法内的变量为线程安全,这是由于方法内的变量是私有的特性造成的。
2、实例变量是非线程安全的,暨在一个方法外,类内,解决方法:加 synchronized关键字。

1、同步方法:暨同步对象,对象锁,不是把一段代码或者方法(函数)当做锁。多个同步方法呢?
2、同步代码快: 
    A: synchronized(this)、<===>同步方法,也是锁定当前对象。
    B: synchronized(string) 又分成员变量(一个和多个)和形参、 变量的情况分为一个
3、synchronized static 静态同步方法 同下   类锁
4、synchronized(Class) 同步类   同上   类锁
5、类锁和对象锁有什么区别?他们是相互独立不冲突的,获取了类锁的线程和获取了对象锁的线程是不冲突的!

以上又分为以下几种情况:
1、线程的多个对象和一个对象
2、多个同步方法,全部同步,容易造成死锁,解决方案:同步块
3、一个同步方法和没有同步的方法的调用
4、多个线程调用 同步A、同步B
5、死锁
6、脏数据

demo:
 

public class Mythread extends Thread {

    private static int count = 5;
    private static ReentrantLock lock =new ReentrantLock();


    @Override
    synchronized public void run() {  // 方法锁
        count --;
        System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
    }

//    @Override
//    synchronized static public void run() {  // 静态方法锁,等价于类锁
//        count --;
//        System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
//    }

//    @Override
//    public void run() {
//
//        super.run();
//        synchronized(this) { // 对象锁
//            count --;
//            System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
//        }
//    }

//    @Override
//    public void run() {
//
//        super.run();
//        synchronized(Mythread.class) { // 类锁
//            count --;
//            System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
//        }
//    }

//    @Override
//    public void run() {  // ReentrantLock
//
//        try{
//            lock.lock();
//            count --;
//            System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
//        }
//        finally
//        {
//            lock.unlock();
//        }
//    }

    public static void main(String args[]) {

        Mythread mythread = new Mythread();

        Thread a = new Thread(mythread, "A");
        Thread b = new Thread(mythread, "B");
        Thread c = new Thread(mythread, "C");
        Thread d = new Thread(mythread, "D");

        a.start();
        b.start();
        c.start();
        d.start();
    }
}

参考:https://www.cnblogs.com/xumanbu/p/4203504.html JAVA中 成员变量和和实例变量区别

转载于:https://my.oschina.net/360yg/blog/3010878

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值