> 文档中心 > Java多线程详解

Java多线程详解


文章目录


文章目录

  • 文章目录
  • 一、多线程的实现
    • 1.继承Thread类
      • 1.设置和获取线程名称
      • 2.线程优先级
      • 3.线程控制
      • 4.线程的生命周期
    • 2.实现Runnable接口的方式实现多线程
  • 二、线程同步
  • 三、线程安全的类
  • 四、Lock锁
  • 五、生产者消费者模式

一、多线程的实现

1.继承Thread类

在这里插入图片描述
案例:

package com.Thread;public class MyThread extends Thread {    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(i); }    }}package com.Thread;public class MyThreadTest {    public static void main(String[] args) { MyThread t1=new MyThread(); MyThread t2=new MyThread();// t1.run();// t2.run(); //start()导致此线程开始执行,java虚拟机调用此线程的run方法 t1.start(); t2.start();    }}

1.设置和获取线程名称

package com.Thread;public class MyThread extends Thread {    public MyThread() {    }    public MyThread(String name) { super(name);    }    @Override    public void run() { for (int i = 0; i <100 ; i++) {     //getName()获取线程名称     System.out.println(getName()+":"+i); }    }}package com.Thread;public class MyThreadTest {    public static void main(String[] args) {// MyThread t1=new MyThread();// MyThread t2=new MyThread();/* //设置线程名称(方式一) t1.setName("小马哥"); t2.setName("小飞侠");*/// t1.run();// t2.run(); //start()导致此线程开始执行,java虚拟机调用此线程的run方法  //设置线程名称(方式二) MyThread t1=new MyThread("小马哥"); MyThread t2=new MyThread("小飞侠"); t1.start(); t2.start();    }}

2.线程优先级

在这里插入图片描述
案例:

package com.priority;public class MyPriority extends Thread {    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(getName()+":"+i); }    }}package com.priority;public class MyPriorityTest {    public static void main(String[] args) { MyPriority p1=new MyPriority(); MyPriority p2=new MyPriority(); MyPriority p3=new MyPriority(); p1.setName("线程一"); p2.setName("线程二"); p3.setName("线程三");// System.out.println(Thread.NORM_PRIORITY);  //5// System.out.println(Thread.MAX_PRIORITY);  //10// System.out.println(Thread.MIN_PRIORITY);  //1 //设置线程优先级 p1.setPriority(1); p2.setPriority(7); p3.setPriority(10);  //线程等级越高获取cpu时间片的几率高 p1.start(); p2.start(); p3.start();    }}

3.线程控制

在这里插入图片描述
案例:

package com.control;public class ThreadSleep extends Thread {    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(getName()+":"+i);     try {  Thread.sleep(1000);     } catch (InterruptedException e) {  e.printStackTrace();     } }    }}package com.control;public class ThreadSleepTest {    public static void main(String[] args) { ThreadSleep s1=new ThreadSleep(); ThreadSleep s2=new ThreadSleep(); ThreadSleep s3=new ThreadSleep(); s1.setName("小马哥"); s2.setName("小飞侠"); s3.setName("老六"); s1.start(); s2.start(); s3.start();    }}
package com.control;public class ThreadJoin extends Thread{    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(getName()+":"+i); }    }}package com.control;public class ThreadJoinTest {    public static void main(String[] args) { ThreadJoin j1=new ThreadJoin(); ThreadJoin j2=new ThreadJoin(); ThreadJoin j3=new ThreadJoin(); j1.setName("老大"); j2.setName("老二"); j3.setName("老三"); j2.start(); //当j2执行完之后,j1,j3才开始执行 try {     j2.join(); } catch (InterruptedException e) {     e.printStackTrace(); } j1.start(); j3.start();    }}
package com.control;public class ThreadDaemon extends Thread {    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(getName()+":"+i); }    }}package com.control;public class ThreadDaemonTest {    public static void main(String[] args) { ThreadDaemon d1=new ThreadDaemon(); ThreadDaemon d2=new ThreadDaemon(); d1.setName("张飞"); d2.setName("关羽"); //设置主线程,主线程执行完毕之后,守护线程也会很快的结束 Thread.currentThread().setName("刘备"); //设置守护线程 d1.setDaemon(true); d2.setDaemon(true); d1.start(); d2.start(); for (int i = 0; i <10 ; i++) {     System.out.println(Thread.currentThread().getName()+":"+i); }    }}

4.线程的生命周期

在这里插入图片描述

2.实现Runnable接口的方式实现多线程

在这里插入图片描述
案例:

package com.Runnable;public class MyRunnable implements Runnable {    @Override    public void run() { for (int i = 0; i <100 ; i++) {     System.out.println(Thread.currentThread().getName()+":"+i); }    }}package com.Runnable;public class MyRunableTest {    public static void main(String[] args) { MyRunnable m=new MyRunnable(); Thread t1=new Thread(m,"小马哥"); Thread t2=new Thread(m,"小飞侠"); t1.start(); t2.start();    }}

二、线程同步

在这里插入图片描述
案例:

package com.SellTicketTest;public class SellTicket implements Runnable {    private int ticket=100;    private Object obj=new Object();    @Override    public void run() { while (true) {     synchronized (obj) {  if (ticket > 0) {      try {   Thread.sleep(100);      } catch (InterruptedException e) {   e.printStackTrace();      }      System.out.println(Thread.currentThread().getName() + "正在售出第" + ticket + "张票");      ticket--;  }     } }    }}package com.SellTicketTest;public class SellTicketTest {    public static void main(String[] args) { SellTicket ticket=new SellTicket(); Thread t1=new Thread(ticket,"窗口一"); Thread t2=new Thread(ticket,"窗口二"); Thread t3=new Thread(ticket,"窗口三"); t1.start(); t2.start(); t3.start();    }}

三、线程安全的类

在这里插入图片描述

四、Lock锁

在这里插入图片描述
案例:

package com.lock;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class MyLock implements Runnable {    private int ticket=100;    private Lock lock=new ReentrantLock();    @Override    public void run() { while (true) {     try {  lock.lock();  if (ticket > 0) {      try {   Thread.sleep(100);      } catch (InterruptedException e) {   e.printStackTrace();      }      System.out.println(Thread.currentThread().getName() + "正在售出第" + ticket + "张票");      ticket--;  }     } catch (Exception e) {  e.printStackTrace();     }finally {  lock.unlock();     } }    }}package com.lock;import com.SellTicketTest.SellTicket;public class MyLockTest {    public static void main(String[] args) { MyLock ticket=new MyLock(); Thread t1=new Thread(ticket,"窗口一"); Thread t2=new Thread(ticket,"窗口二"); Thread t3=new Thread(ticket,"窗口三"); t1.start(); t2.start(); t3.start();    }}

五、生产者消费者模式

在这里插入图片描述

 class Box{private int milk;private boolean state=false;public synchronized void put(int milk)  {//同步代码块:执行这块代码后,所在线程加锁,不会被抢占使用权。  //这时其他线程要执行,需要wait()该线程,notify()其他线程if(state) {  //有奶,不再继续放,put的线程暂停,等待get线程拿出奶try {wait();} catch (InterruptedException e) {e.printStackTrace();}}//state=false,没有奶,生产者放入奶,这是第i瓶this.milk=milk;System.out.println("生产者放入第"+this.milk+"瓶奶");state=true;   //有了奶,奶箱不为空,修改奶箱状态notifyAll();  //唤醒其他所有线程(唤醒get线程,取出牛奶)}public synchronized void get()  {if(!state) {  //state=false,没有奶,消费者没法拿出奶,只能等待try {wait();  //消费者的get行为/线程开始等待} catch (InterruptedException e) {e.printStackTrace();}}//state=true,有奶,可以拿出,这是第i瓶奶System.out.println("消费者拿出第"+this.milk+"瓶奶");state=false; //拿出以后,box空,修改box状态notifyAll();  //唤醒其他所有线程(唤醒put线程,开始放入)}} class Producer implements Runnable{private Box b;public Producer(Box b) {this.b=b;}@Overridepublic void run() {for(int i=1;i<11;i++) {b.put(i);}}   } class Customer implements Runnable{private Box b;public Customer(Box b) {this.b=b;    }@Overridepublic void run() {while(true) {b.get();}}} public class Milk {public static void main(String[] args) {Box b=new Box();    //创建一个奶箱Producer p=new Producer(b);  //都用这个奶箱Customer c=new Customer(b);Thread t1=new Thread(p);    //producer在线程1中Thread t2=new Thread(c);    //customer在线程2中t1.start();t2.start();}}

开发者涨薪指南 Java多线程详解 48位大咖的思考法则、工作方式、逻辑体系