JUC高并发编程学习1

什么是JUC

Java.util.Concurrent 包

进程和线程

  1. 区别:一个进程中可以有多个线程执行
  2. 线程状态
   public enum State {
   
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,(新建)

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,(准备就绪)

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,(阻塞)

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,(不见不散)

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,(过时不候)

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;(终结)
    }
  1. wait和sleep区别
    sleep是Thread的静态方法;wait是Object的方法任何对象实例都可以调用
    /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis 参数是睡眠的毫秒数
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *如果秒数是负的抛出异常
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

    /**
     * Causes the current thread to wait until another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object.
     * In other words, this method behaves exactly as if it simply
     * performs the call {@code wait(0)}.
     * <p>
     * The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method. The thread then waits until it can
     * re-obtain ownership of the monitor and resumes execution.
     * <p>
     * As in the one argument version, interrupts and spurious wakeups are
     * possible, and this method should always be used in a loop:
     * <pre>
     *     synchronized (obj) {
     *         while (&lt;condition does not hold&gt;)
     *             obj.wait();
     *         ... // Perform action appropriate to condition
     *     }
     * </pre>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.
     *
     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of the object's monitor.
     * @throws  InterruptedException if any thread interrupted the
     *             current thread before or while the current thread
     *             was waiting for a notification.  The <i>interrupted
     *             status</i> of the current thread is cleared when
     *             this exception is thrown.
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    public final void wait() throws InterruptedException {
   
        wait(0);
    }

sleep不会释放锁,也不需要占用锁;wait会释放锁,当被notify时
都可以被interrupted方法中断
4. 管程,就是Monitor监视器,也被称为锁。是一种同步机制,保证同一时间,只有一个线程访问被保护的数据或者代码。JVM中同步进入和退出都是基于管程对象实现的
5. 用户线程和守护线程
用户线程:自定义线程
守护线程:比如垃圾回收
示例:主线程结束了,用户线程还在运行,jvm存活

public class Test {
   
    public static void main(String[] args) {
   
        Thread thread = new Thread(() -> {
   
            System.out.println(Thread.currentThread().getName() + "----" + Thread.currentThread().isDaemon());
            while(true){
   

            }
        },"aa");
        thread.start();

        System.out.println(Thread.currentThread().getName()+"  over");
    }
}

在这里插入图片描述

示例: 没有用户线程了,都是守护线程,jvm结束

package com.example.juclearn;

public class Test {
   
    public static void main(String[] args) {
   
        Thread thread = new Thread(() -> {
   
            System.out.println(Thread.currentThread().getName() + "----" + Thread.currentThread().isDaemon());
            while(true){
   

            }
        },"aa");
        thread.setDaemon(true);
        thread.start();

        System.out.println(Thread.currentThread().getName()+"  over");
    }
}

在这里插入图片描述

========================= Lock接口 ==============================

Synchronized关键字

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,作用范围是{}括起来的代码,作用对象是调用这个代码块的对象
  2. 修饰一个方法,被修饰的方法成为同步方法,作用范围是整个方法,作用对象是调用这个方法的对象。synchronized关键字不能被继承
  3. 修饰一个静态的方法,作用范围是整个静态方法,作用的对象是这个类的所有对象
  4. 修饰一个类,作用范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象

Synchronized实现卖票例子

package com.example.juclearn;

/**
 * 多线程编程实现卖票例子 3个售货员卖30张票
 */

/**
 * 第一步,创建资源类,在类中创建属性和操作方法
 */

class Ticket{
   
    private int number = 30;

    /**
     * 售票方法
     */
    public synchronized void sale(){
   
        if (number > 0){
   
            System.out.println(Thread.currentThread().getName() + "卖第"+ (30-number--+1) +"张票,还剩" + number + "张");
        }
    }

}
public class TestSynchronized {
   
    public static void main(String[] args) {
   
        Ticket ticket = new Ticket();
//        创建多个线程 调用资源类的方法

        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 0; i < 40; i++){
   
                    ticket.sale();
                }

            }
        }, "AA").start();
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 0; i < 40; i++){
   
                    ticket.sale();
                }
            }
        }, "BB").start();
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 0; i < 40; i++){
   
                    ticket.sale();
                }
            }
        }, "CC").start();
    }
}

Lock接口

  1. 实现了比使用synchronized方法和语句可获得的更广泛的锁定操作
  2. 实现类有ReentrantLock(可重入锁)、ReentrantreadWriteLock.ReadLock、ReentrantreadWriteLock.WriteLock
  3. Lock 和Synchronized区别
    Lock不是Java语言内置的,是一个类;Synchronized是Java语言的关键字,是内置的
    synchronized不需要用户手动释放锁;Lock必须手动释放锁,否则会出现死锁
    Lock可以让等待锁的线程响应中断;Synchronized会让等待的线程一直等待下去
    Lock可以得知有没有获得锁;Synchronized不能
    Lock可以提高多个线程进行读操作的效率
package com.example.juclearn.lock;
/**
 * 多线程编程实现卖票例子 3个售货员卖30张票
 */

import java.util.concurrent.locks.ReentrantLock;

/**
 * 第一步,创建资源类,在类中创建属性和操作方法
 */

class Ticket{
   
    private int number = 30;

    private final ReentrantLock reentrantLock = new ReentrantLock();

    /**
     * 售票方法
     */
    public  void sale(){
   
        reentrantLock.lock();
        try {
   
            if (number > 0){
   
                System.out.println(Thread.currentThread().getName() + "卖第"+ (30-number--+1) +"张票,还剩" + number + "张");
            }
        }finally {
   
            reentrantLock.unlock();
        }
    }

}
public class TestLock {
   
    public static void main(String[] args) {
   
        //        创建多个线程 调用资源类的方法
        Ticket ticket = new Ticket();

        new Thread(() -> {
   
            for (int i = 0; i < 40; i++) {
   
                ticket.sale();
            }
        },"AA").start();

        new Thread(() -> {
   
            for (int i = 0; i < 40; i++) {
   
                ticket.sale();
            }
        },"BB").start();

        new Thread(() -> {
   
            for (int i = 0; i < 40; i++) {
   
                ticket.sale();
            }
        },"CC").start();
    }
}

注:start方法最终调用的本地方法,何时调用由操作系统决定

========================= 线程间通信 ============================
多线程编程步骤:
1 创建资源类,创建属性和方法
2 在资源类中判断、干活、通知(新增)
3 创建多个线程,调用资源类的操作方法

Synchronized实现案例

实例:有两个线程其中一个线程实现对值 +1,另一个线程实现对值 -1

package com.example.juclearn.sync;

class Share {
   
    private int number = 0;

    public synchronized void incr() throws InterruptedException {
   
//        判断
        if (number != 0){
   
            this.wait();
        }
//        干活
        number++;
        System.out.println(Thread.currentThread().getName() + "::"  + number);
//        通知
        this.notifyAll();
    }

    public synchronized void decr() throws InterruptedException {
   
//        判断
        if (number != 1){
   
            this.wait();
        }
//        干活
        number--;
        System.out.println(Thread.currentThread().getName() + "::"  + number);
//        通知
        this.notifyAll();
    }

}
public class ThreadComDemo1 {
   
    public static void main(String[] args) {
   
        Share share = new Share();
        new Thread(()->{
   
            for (int i = 0; i <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值