java开发两年,连这些多线程知识都还没掌握,你凭什么涨薪!

时间:2020-09-17 13:05:06   收藏:0   阅读:35
并发与并行

线程与进程

主线程:
技术图片

  1. 通过继承Thead类,java.lang.Thead;重写Thead中的run方法,在run方法中设置我们的线程任务,调用start()方法,开启新的线程,执行run方法
public class TheadTest extends Thread{
 @Override
 public void run() {
    for (int i = 0; i < 10; i++){
        System.out.println(i);
    }
 }
TheadTest theadTest = new TheadTest();
 theadTest.start();

多线程的运行原理:

多线程内存图解:
技术图片

多个线程之间是互不影响的,因为在不同的栈空间

Thred类的常用方法

  1. 获取线程名:
  1. 设置线程的名称:
  1. static void sleep(long millis)

实现Runnable 接口

public class RunnableThead implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5 ; i++) {
            System.out.println(i);
        }
    }
   RunnableThead runnableThead = new RunnableThead();
   new Thread(runnableThead).start();

- Runnable接口创建多线程和继承Thread类创建多线程的区别:

匿名内部类的方式实现线程的创建

@Test
    public void testThread(){
        new Thread("线程一"){
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(getName()+i);
                }
            }
        }.start();
    }
    @Test
    public void testRunnable(){
        new Thread( new Runnable(){
            @Override
            public void run() {
                System.out.println("匿名线程");
            }
        }).start();
    }

线程安全问题:

public class TicketThead extends Thread{
    public static void saleTicket(String ThreadName){
        for (int i = 10; i > 0 ; i--){
            System.out.println(ThreadName+"_"+ i);
        }
    }
    @Test
   public void testTicketThrea(){
        TicketThead ticketThead = new TicketThead();
        new Thread("线程1"){
            @Override
            public void run() {
                String name = getName();
                ticketThead.saleTicket(name);
            }
        }.start();
        new Thread("线程2"){
            @Override
            public void run() {
                ticketThead.saleTicket(getName());
            }
        }.start();
        new Thread("线程3"){
            @Override
            public void run() {
                ticketThead.saleTicket(getName());
            }
        }.start();
    }
}

多线程安全问题的原理分析:

技术图片

4.2 线程同步技术解决线程安全问题

  1. 同步代码块
格式:synchronized(锁对象){
    可能出现线程安全问题的代码(访问了共享数据的代码)
}
 private int ticket = 100;
        Object obj = new Object();
        @Override
        public void run() {
            while (true) {
                synchronized(obj){
                    if (ticket > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket--);
                    }
                }
            }
        }

同步代码块的原理

技术图片

  1. 同步方法
public void run() {
            while (true) {
               saleTicket();
            }
        }
private synchronized void saleTicket(){
    if (ticket > 0) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket--);
    }
}
  private static /*synchronized*/ void saleTicket(){
            synchronized(Runnable.class){
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket--);
                }
            }
        }

3. 锁机制

public void run() {
            while (true) {
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket--);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        lock.unlock();
                    }
                }
            }
        }

线程的状态

技术图片

等待唤醒(线程之间的通信)

public static void main(String[] args) {
        Object obj = new Object();
        new Thread("顾客线程"){
            @Override
            public void run() {
                synchronized (obj){
                    System.out.println(getName()+"告知老板要买的包子数量和种类!");
                    try {
                        obj.wait();  //释放了锁对象
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("开吃包子咯");
                }
            }
        }.start();
        new Thread("老板线程"){
            @Override
            public void run() {
                synchronized (obj){
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+"告知顾客包子做好了");
                    obj.notify();
                }
            }
        }.start();
    }

等待唤醒机制(线程间的通信)

//线程一
public class BaoZiPu extends Thread{
    private BaoZi bz;

    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }
    @Override
    public void run() {
        synchronized (bz){
            if (bz.flag == true){
                try {
                    bz.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (bz.flag == false){
                bz.name = "叉烧包";
                System.out.println(getName() + ":" + "开始生产"+bz.name+"包子");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("生产好了包子");
                bz.flag = true;
                bz.notify();
            }
        }
    }
//线程二
public class Consumer extends Thread {
    private BaoZi bz;

    public Consumer(BaoZi bz) {
        this.bz = bz;
    }

    @Override
    public void run() {
        synchronized (bz){
            if (bz.flag == false){
                try {
                    bz.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (bz.flag == true){
                System.out.println( getName() + ":" + "开吃" + bz.name + "包子!");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("包子吃完了!");
                bz.notify();
                bz.flag = false;
            }
        }
    }
}
//
 BaoZi bz = new BaoZi();//传入的锁对象是同一个
new BaoZiPu(bz).start();
new Consumer(bz).start();

线程池:

技术图片

ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new RunnableThead());

最后

感谢你看到这里,文章有什么不足还请指正,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!