Java的多线程编程

1.Java的多线程来源

1.西计算硬件系统的支持,cpu是多核处理器,计算机体系本来就是多个数据来源。

2.Java的线程

1.Java线程的类型

1.Thread

Thread实现Runable接口

// Thread 实现Runnable接口
public class Thread implements Runnable {}
// Thread内部定义的线程生命周期的状态
public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;
    }

Thread中的构造方法

 

Thread中的public方法

 

run()和start()的区别 ,run()是在同一线程开启执行方法,start()通过native方法开启新的线程等待系统调用执行。

@Override
public void run() {
    if (target != null) {
         target.run();
    }
}


public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        // Android-changed: Replace unused threadStatus field with started field.
        // The threadStatus field is unused on Android.
        if (started)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        // Android-changed: Use field instead of local variable.
        // It is necessary to remember the state of this across calls to this method so that it
        // can throw an IllegalThreadStateException if this method is called on an already
        // started thread.
        started = false;
        try {
            // Android-changed: Use Android specific nativeCreate() method to create/start thread.
            // start0();
            nativeCreate(this, stackSize, daemon);
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

wait()和sleep()的区别,wait()放弃了cpu的占用,sleep()占用了cpu的运行在等待.

 

2.Runable

 

3.Callable和Future

 

2.线程操作,中断,合并,让出,睡眠

 

3.线程同步操作Synchronized和Volatile,Lock

synchronized:作用于方法上和对象上,使方法和对象只能被一个线程访问。每一个查询都是一个内核操作。

volatile:使用于数据,使对数据的操作成为一个整体。不被多线程分割成多步骤。

lock:

synchronized和lock的区别:1.synchronized自动释放,lock手动释放。2.synchronized是语言提供的关键字在jvm层面提供实现机制,lock是Java方法提供的类用户可以自定义。3.synchronize d不可以获取到获取锁的状态,lock可以获取到获取锁的状态这样用户可以根据状态处理下一步的运行。4.synchronized是可重入锁,不可以中断,非公平,lock锁是可重入,公平,可判断。

 

4.CAS机制

CAS的全称为compare and swap简单的解释为比较交换,CAS有三个操作数,内存V,旧的预期值A,要修改的新值B,当且仅当预期值A和内存值相同时,将内存值V修改成B,否则什么都不做。这个过程发生在内存中的,是汇编语言的一个操作过程。那么乐观锁为什么用CAS算法呢?简单的来说就是乐观锁每次操作的时候都认为不会发生并发,但是为了安全还是会去检测是否并发了,这样的话不用sync耗费太大性能。

5.ThreadLocal

 

6.计数工具Atomic*类的数据

Atomic包是java.util.concurrent下的另一个专门为线程安全设计的Java包,包含多个原子操作类。

  • 标量类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference

  • 数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray

  • 更新器类:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater

  • 复合变量类:AtomicMarkableReference,AtomicStampedReference

原理分析:

    unsafe在sum.misc包中,直接操作对象内存,修改jvm运行时的数据操作上不是通过类修改地址,而是直接通过地址修改数据。通过代码可以看出保证原子性是通过自旋+cas乐观锁。在这个过程中,通过compareAndSwapInt比较更新value值,如果更新失败,重新获取旧值,然后更新。

  CAS相对于其他锁,不会进行内核态操作,有着一些性能的提升。但同时引入自旋,当锁竞争较大的时候,自旋次数会增多。cpu资源会消耗很高。

       换句话说,CAS+自旋适合使用在低并发有同步数据的应用场景。

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
    private static final long VALUE;

    static {
        try {
            VALUE = U.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (ReflectiveOperationException e) {
            throw new Error(e);
        }
    }

    private volatile int value;

    /**
     * Creates a new AtomicInteger with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    /**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return U.getAndAddInt(this, VALUE, 1);
    }
 }

其中的getAndAddInt方法我们再找源码

// var1:对象的引用
// var2:值的偏移量
// var3:期望值
// var4:更新值
//这个方法的作用就是拿着对象的引用以及位偏移量从内存中拿到值,然后拿着这个值和期望值进行一个比较,如果相同则将要更新的值放到内存中返回true如果不同则返回false.

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);//1
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//2
    return var5;
}

 

7.java8做出的改进

  在Java 8中引入了4个新的计数器类型,LongAdder、LongAccumulator、DoubleAdder、DoubleAccumulator。他们都是继承于Striped64。较之之前的技术工具引入了分段锁的概念。当竞争不激烈的时候,所有线程都是通过CAS对同一个变量(Base)进行修改,当竞争激烈的时候,会将根据当前线程哈希到对于Cell上进行修改(多段锁)。

3.Java线程池

1.

4.多线程的容器

1.容器的安全性

BlockingQueue

5.多线程的常见框架

Rxjava框架

6.Android中多线程的同步

Handle机制

7.Android中多线程的常见工具整理

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MatrixData

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值