Java多线程

从一道题开始

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多线程_第1张图片
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多线程)