美文网首页
Java多线程

Java多线程

作者: 林里icer | 来源:发表于2018-03-13 21:11 被阅读0次

从一道题开始

java三个线程分别打印ABC,按“ABC”顺序打印十遍,嗯嗯

分析

多线程问题,查了不少资料写出了代码。

1.java线程状态

New (新建状态):新创建了一个线程对象
Runnable (就绪状态):线程对象创建后,调用了该对象的start()方法之后,该状态的线程就位于可运行线程池中,变得可运行,等待获取CPU的使用权
Running (运行状态):就绪状态的线程获取了CPU,开始执行程序代码
Blocked (阻塞状态):线程因为某种原因放弃了CPU使用权,暂时停止运行状态,知道再次进入Runnable状态,才有机会再次Running。
阻塞情况分为三种:
①等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待线程池里(wait会释放持有的锁)
②同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用、或者I/O处理完毕时,线程重新转入就绪状态。(需要注意,sleep不会释放持有的锁)
③其他阻塞:运行的线程执行sleep()或join()方法时,JVM会把线程设置为阻塞
Dead (死亡状态):线程执行完毕或者由于异常退出了run方法,该线程结束了生命周期

如图


Java Thread.png

2.线程方法

①join方法:

join方法使当前线程阻塞,等待调用join方法的线程执行,可以使得线程之间的并行执行变为串行执行

举个例子:

main(){
    ThreadJoinTest t1 = new ThreadJoinTest("小明");
    ThreadJoinTest t2 = new ThreadJoinTest("小东");
    t1.start();
    t1.join();
    t2.start();
}

程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕。所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会

②sleep方法
sleep方法暂停当前线程,把CPU片段让出给其他线程,减缓当前线程的执行。休眠时间结束,线程进入就绪状态

③yield方法
yield方法使线程进入就绪状态,所以执行yield()的线程有可能在进入到就绪状态后马上又被执行。

④wait方法和notify方法
wait方法使当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程就被唤醒(进入“就绪状态”)
notify方法是唤醒单个进程,notifyAll是唤醒所有进程

3.锁

以多窗口售票系统为例,剩余票的数量是固定的,所有窗口共享这个数值。锁的存在,就保证了在同一时间只有一个线程访问方法或变量,保证了“同步”。

题解

思路:创建三个线程,每个线程持有两把锁,是自身对象锁和前一个线程的对象所。

MyThread.class

public class MyThread implements Runnable{

    private String name;
    private Object pre;
    private Object self;

    public MyThread(String name,Object pre,Object self) {
        this.name = name;
        this.pre = pre;
        this.self = self;
    }

    @Override
    public void run() {

        for (int i=0;i<11;i++) {
            synchronized (pre) {
                synchronized (self) {
                    System.out.println(name);
                    self.notify();
                }
                try{
                    //最后一次,防止死锁
                    if (i<10) pre.wait();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Main

import static java.lang.Thread.sleep;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();

        Thread A = new Thread(new MyThread("A",c,a));
        Thread B = new Thread(new MyThread("B",a,b));
        Thread C = new Thread(new MyThread("C",b,c));

        A.start();
        //保证A B C执行顺序
        sleep(10);
        B.start();
        sleep(10);
        C.start();
    }
}

相关文章

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • java多线程--Callable

    **移步[java多线程系列文章]Java多线程(二十二)---LockSupport工具Java 停止线程 一、...

  • android 多线程 — 线程的面试题和答案

    这里都是我从各个地方找来的资料,鸣谢: Java多线程干货系列—(一)Java多线程基础 JAVA多线程和并发基础...

  • 5月份第一周学习安排

    学习内容: java多线程及线程同步的方法(使用) java多线程各种同步方法的原理和优缺点 java多线程设计模...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • Java基础(六)

    多线程 Java多线程并发 1.1 JAVA 并发知识库 1.2 JAVA 线程实现/创建方式 1.2.1 继承 ...

  • (五) volatile关键字

    Java多线程目录 1 背景 理解Java多线程的内存抽象逻辑请阅读java多线程内存模型,当代操作系统,处理器为...

  • Java多线程高级特性(JDK8)

    [TOC] 一、Java多线程 1.Java多线程基础知识 Java 给多线程编程提供了内置的支持。一条线程指的是...

网友评论

      本文标题:Java多线程

      本文链接:https://www.haomeiwen.com/subject/gvswvxtx.html