关于java:java基础之十七多线程

9次阅读

共计 3487 个字符,预计需要花费 9 分钟才能阅读完成。

一、线程根底内容

1、程序、过程与线程



1、程序:Program, 是一个指令的汇合
2、过程:Process,(正在执行中的程序) 是一个动态的概念

过程是程序的一次动态执行过程,占用特定地的地址空间
每个过程都是独立的,由 3 局部组成 cpu,data,code
毛病:内存的节约,cpu 的累赘

3、线程: 是过程中一个“繁多的间断管制流程”/ 执行门路

线程又被成为轻量级过程
Threads run at the same time,independently of one another
一个过程可领有多个并行的线程
一个过程中的线程共享雷同的内存单元 / 内存地址空间 -> 能够拜访雷同的变量和对象,而且他们从同一堆中调配对象 -> 通信、数据交换、同步操作
因为线程间的通信是在同一地址空间上进行的,所以不须要额定的通信机制,这就使得通信更简便而且信息的传递速度也更快

2、线程的创立和启动

2.1、第一种形式


继承 Thread 类,从新 run 办法,调 start(启动线程),每次运行雷同的代码,进去的后果可能不一样,起因在于多线程谁先抢占资源无奈进行认为管制

package com.msbline.threadPkg;
public class ThreadDemo extends Thread{
    @Override
 public void run() {for (int i = 0; i < 10; i++){System.out.println(Thread.currentThread().getName() +"---"+ i);
        }
    }
    public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();
        for (int i = 0; i < 10; i++){System.out.println(Thread.currentThread().getName() +"==="+ i);
        }
    }
}
2.2、第二种形式


实现 Runnable 接口,重写 run 办法,创立 Thread 对象,将刚刚创立好的 Runnable 的子类实现作为 Thread 的结构参数,通过 Trhead.start()进行启动

package com.msbline.threadPkg;
public class ThreadDemo02 implements Runnable{
    @Override
 public void run() {for (int i = 0; i < 10; i++){System.out.println(Thread.currentThread().getName() +"---"+ i);
        }
    }
    public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();
        new Thread(threadDemo).start();
        for (int i = 0; i < 10; i++){System.out.println(Thread.currentThread().getName() +"==="+ i);
        }
    }
}
两种形式哪种应用更多


3、线程的生命周期



4、线程的代理设计模式

5、线程操作的相干办法

1、sleep 办法是属于 Thread 类中的,sleep 过程中线程不会开释锁,只会阻塞线程,让出 cpu 给其余线程,然而他的监控状态仍然放弃着,当指定的工夫到了又会主动复原运行状态,可中断,sleep 给其余线程运行机会时不思考线程的优先级,因而会给低优先级的线程以运行的机会

2、yield 和 sleep 一样都是 Thread 类的办法,都是暂停以后正在执行的线程对象,不会开释资源锁,和 sleep 不同的是 yield 办法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只须要期待从新获取 CPU 执行工夫,所以执行 yield()的线程有可能在进入到可执行状态后马上又被执行。还有一点和 sleep 不同的是 yield 办法只能使同优先级或更高优先级的线程有执行的机会

3、join,期待调用 join 办法的线程完结之后,程序再继续执行,个别用于期待异步线程执行完后果之后能力持续运行的场景。例如:主线程创立并启动了子线程,如果子线程中药进行大量耗时运算计算某个数据值,而主线程要获得这个数据值能力运行,这时就要用到 join 办法了

4、wait 办法是属于 Object 类中的,wait 过程中线程会开释对象锁,只有当其余线程调用 notify 能力唤醒此线程。wait 应用时必须先获取对象锁,即必须在 synchronized 润饰的代码块中应用,那么相应的 notify 办法同样必须在 synchronized 润饰的代码块中应用,如果没有在 synchronized 润饰的代码块中应用时运行时会抛出 IllegalMonitorStateException 的异样

二、线程同步

1、线程同步的必要性


多个线程拜访同一个共享数据的时候,会呈现数据安全问题,比方买票,两个线程同时对一张票进行操作,可能会导致重票的问题

2、线程同步的实现

2.1、同步代码块

synchronized(共享资源,共享对象,须要是 Object 的子类){具体执行的代码块}

public class TicketRunnable2 implements Runnable{
    private int ticket = 5;
    @Override
 public void run() {for(int i = 0; i<100; i++){
            try {Thread.sleep(1000);
            } catch (InterruptedException e) {e.printStackTrace();
            }
            synchronized (this){if(ticket > 0){System.out.println(Thread.currentThread().getName()+"正在发售第"+(ticket--)+"票");
                }
            }
        }
    }
    public static void main(String[] args) {TicketRunnable2 ticketRunnable = new TicketRunnable2();
        Thread t1 = new Thread(ticketRunnable,"A");
        Thread t2 = new Thread(ticketRunnable,"B");
        Thread t3 = new Thread(ticketRunnable,"C");
        Thread t4 = new Thread(ticketRunnable,"D");
        t1.start();
        t2.start();
        t3.start();
        t4.start();}
}
2.2、同步办法
public class TicketRunnable3 implements Runnable{
    private int ticket = 5;
    @Override
 public void run() {for(int i = 0; i<100; i++){
            try {Thread.sleep(1000);
            } catch (InterruptedException e) {e.printStackTrace();
            }
            this.sale();}
    }
    /**
 * 应用同步办法解决
 */
 public synchronized void sale(){if(ticket > 0){System.out.println(Thread.currentThread().getName()+"正在发售第"+(ticket--)+"票");
        }
    }
    public static void main(String[] args) {TicketRunnable3 ticketRunnable = new TicketRunnable3();
        Thread t1 = new Thread(ticketRunnable,"A");
        Thread t2 = new Thread(ticketRunnable,"B");
        Thread t3 = new Thread(ticketRunnable,"C");
        Thread t4 = new Thread(ticketRunnable,"D");
        t1.start();
        t2.start();
        t3.start();
        t4.start();}
}

3、死锁

4、线程同步小结

三、线程间通信

1、线程间通信的必要性


一般来说,每个线程本人实现本人的工作就能够了,但有时候,线程的解决会依赖另一个线程的数据,所以就须要线程间通信,来达到同步信息的成果。

2、线程间通信的实现

参考:https://blog.csdn.net/jisuanji12306/article/details/86363390

正文完
 0