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();}}
开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系