JUC并发编程(一)

1.什么是JUC?

业务:普通的线程代码 Thread

Runnable 没有返回值,效率相比Callable相对较低!

2.线程和进程

进程:一个程序,QQ.exe,Music.exe 程序的集合

一个进程往往可以有多个线程,至少包含一个

java默认有两个线程,main GC

线程:开了一个进程Typro ,写字,自动保存(线程负责)

java真的可以开启线程吗? 开不了

并发,并行

并发编程:并发,并行

并发(多个线程操作同一个资源)

​ ·cpu一核,模拟出来多线程,快速交替

并行(多个人一起行走)

​ ·cpu多核,多个线程可以同时执行 线程池

package com.xizi.demo01;
​
public class Test {
    public static void main(String[] args) {
        //获取cpu的核数
        //cpu密集型,IO密集型
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}

并发编程的本质:充分利用CPU的资源


线程有几个状态

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;
    //终止
}

wait/sleep区别

1.来自不同的类

​    wait=>Object

​    sleep=>Thread

2.关于锁的释放

​    wait会释放锁,sleep睡觉了,不会释放锁

3.是哟个的范围是不同的

​    wait:必须在同步代码块中

​    sleep:可以在任何地方睡

4.是否要捕获异常

​    wait:不需要捕获异常

​    sleep:必须要捕获异常

3.Lock锁

传统方式实现Runnable接口 耦合性太差

优化后的传统方式 买票方式

Synchronized

package com.xizi.demo01;
​
public class SaleTicketTest {
    public static void main(String[] args) {
        //并发:多个线程操作同一个资源,把资源丢入线程
        Ticket ticket = new Ticket();
        new Thread(()->{
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"C").start();
    }
​
}
//资源类 OOP
class Ticket{
    //属性 方法
    private int number=30;
    //买票的方式
    //synchronizedd 本质:队列,锁
    public synchronized void sale(){
        if (number>0){
            System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余"+number+"张");
        }
    }
}

 

lock方式

package com.xizi.demo01;
​
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
​
public class SaleTicketTest2 {
    public static void main(String[] args) {
        //并发:多个线程操作同一个资源,把资源丢入线程
        Ticket2 ticket2 = new Ticket2();
        new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"A").start();
        new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"B").start();
        new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"C").start();
​
​
    }
}
​
    //Lock 三部曲
//1.new ReentrantLock();
//2.lock.lock(); 加锁
//3.finally=>  lock.unlock();   解锁
class Ticket2 {
        //属性 方法
        private int number = 30;
​
        Lock lock = new ReentrantLock();
​
        //买票的方式
        public void sale() {
              lock.lock();  //加锁
            try {
                //业务代码
                if (number > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "张票,剩余" + number + "张");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); //解锁
            }
        }
    }

Synchronized和Lock区别

1.Synchronized 内置的Java字 Lock是一个Java类

2.Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁

3.Synchronized 会自动释放锁 Lock必须要手动释放锁! 如果不释放锁,死锁

4.Synchronized 线程1(获取锁,阻塞)线程2(等待, 傻傻的等待);lock锁就不一定会等待下去

5.Synchronized 可重入锁, 不可以中断的 非公平;lock 可重入锁, 非公平(可以自己设置);

6.Synchronized 适合锁少量的代码同步问题 ;lock可以锁大量的代码同步问题;

生产者消费者问题

Synchronized版本

package com.xizi.pc;
​
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
​
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
​
}
class Data{
    private  int number=0;
​
    public synchronized void increment() throws InterruptedException {
        if (number!=0){
            // 如果不等于0  等待
            this.wait();
        }
        //等于0 +1
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程 我+1完毕了
        this.notifyAll();
    }
    public synchronized void decrement() throws InterruptedException {
        if (number==0){
            // 如果等于0  等待
            this.wait();
        }
        //不等于0 -1
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程 我+1完毕了
        this.notifyAll();
    }
}

面试的:单例模式 排序算法 生产者和消费者 死锁

问题存在 A B C D四个线程

package com.xizi.pc;

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }

}
class Data{
    private  int number=0;

    public synchronized void increment() throws InterruptedException {
        while (number!=0){
            // 如果不等于0  等待
            this.wait();
        }
        //等于0 +1
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程 我+1完毕了
        this.notifyAll();
    }
    public synchronized void decrement() throws InterruptedException {
        while (number==0){
            // 如果等于0  等待
            this.wait();
        }
        //不等于0 -1
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程 我+1完毕了
        this.notifyAll();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/105347045