JAVA线程池学习
线程的三种实现方式
-
继承Thread类
public class MyThreadClass { public static void main(String[] args) { ThreadTest threadTest = new ThreadTest(); threadTest.start(); for (int i = 0; i < 2000; i++) { System.out.println("----主线程"); } } static class ThreadTest extends Thread { @Override public void run() { for (int i = 0; i < 2000; i++) { System.out.println("子线程"); } } } }- 打印结果为交替打印;总结:注意,线程开启不一定是立即执行的,而是由CPU调度执行
-
实现Runnable接口
package com.phil.gui1; //创建线程方法:实现runnable接口,重写run方法,执行程序需要丢入runnable接口来实现,调用start方法 public class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("========子线程"); } } public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); new Thread(myRunnable).start(); for (int i = 0; i < 200; i++) { System.out.println("----主线程"); } } }-
步骤
实现Runnable接口
重写run() 方法
创建执行
创建包含执行对象Thread,并启动
-
-
实现Callable接口
package com.phil.gui1; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class TestCallAble implements Callable<Boolean> { @Override public Boolean call() throws Exception { System.out.println(">>>>>>" + Thread.currentThread().getName()); for (int i = 0; i < 2000; i++) { try { Thread.currentThread().sleep(1); }catch (Exception e) { e.printStackTrace(); } System.out.println("---->我是子线程"); } return true; } public static void main(String[] args) { TestCallAble t1 = new TestCallAble(); //任务管理器 ExecutorService er = Executors.newFixedThreadPool(1); //执行 Future<Boolean> submit = er.submit(t1); //获取执行结果 // try { // Boolean aBoolean = submit.get(); // }catch (Exception e) { // e.printStackTrace(); // } er.shutdown(); System.out.println(">>>>>>---" + Thread.currentThread().getName()); for (int i = 0; i < 2000; i++) { System.out.println("我是主线程"); } } }-
步骤
实现Callable接口
重写call() 方法
创建执行对象
获取任务管理器
任务管理器提交执行任务对象启动
关闭任务管理器
-
静态代理
package com.phil.gui1;
public class AgencyTest {
public static void main(String[] args) {
PersonI person = new PersonI();
Agency agency = new Agency(person);
agency.merry();
}
}
interface Person{
public void merry();
}
class PersonI implements Person{
@Override
public void merry() {
System.out.println("结婚啦!");
}
}
class Agency{
Person person;
Agency(Person person) {
this.person = person;
}
public void before(){
System.out.println("结婚前准备");
}
public void after() {
System.out.println("结婚后收拾");
}
public void merry() {
before();
this.person.merry();
after();
}
}
- Thread的start方法就是用的静态代理
Lamda表达式推导
-
注意:接口内只有一个抽象方法,可以用Lamda表达式
-
正常的接口和实现
package com.phil.gui1; public class LamdaTest { public static void main(String[] args) { IStudent student = new Student(); student.study("小明"); } } interface IStudent{ void study(String name); } class Student implements IStudent { @Override public void study(String name) { System.out.println(name + "正在学习!"); } } -
静态内部类
package com.phil.gui1; //内静态部类 public class LamdaTest2 { static class Student2 implements IStudent2 { @Override public void study(String name) { System.out.println(name + "正在学习!"); } } public static void main(String[] args) { IStudent2 student2 = new Student2(); student2.study("小明"); } } interface IStudent2{ void study(String name); } -
接口的直接实现
package com.phil.gui1; //接口直接实现 public class LamdaTest3 { public static void main(String[] args) { IStudent3 student3 = new IStudent3() { @Override public void study(String name) { System.out.println(name + "体温异常"); } }; student3.study("您的"); } } interface IStudent3{ void study(String name); } -
局部类
package com.phil.gui1; //局部类 public class LamdaTest3 { public static void main(String[] args) { class Student3 implements IStudent3 { @Override public void study(String name) { System.out.println(name + "正在学习!"); } } IStudent3 student3 = new Student3(); student3.study("小明"); } } interface IStudent3{ void study(String name); } -
Lamda表达式
package com.phil.gui1; //局部类 public class LamdaTest4 { public static void main(String[] args) { IStudent4 student4 = (String name) -> { System.out.println(name + "正在学习!"); }; student4.study("小明"); } } interface IStudent4 { void study(String name); } -
Lamda表达式简化
package com.phil.gui1; //局部类 public class LamdaTest4 { public static void main(String[] args) { //原始表达式 IStudent4 student4 = (String name) -> { System.out.println(name + "正在学习!"); }; student4.study("小明"); //简化1:去掉参数的类型 student4 = (name) -> { System.out.println(name + "正在学习!"); }; student4.study("小明1"); //简化2:去掉参数的括号 student4 = name -> { System.out.println(name + "正在学习!"); }; student4.study("小明2"); //简化3:去掉函数的花括号 student4 = name -> System.out.println(name + "正在学习!"); student4.study("小明3"); } } interface IStudent4 { void study(String name); }
线程的几种方法
-
线程停止
使用变量标识符(定义一个bool变量来强制终止线程)
-
线程休眠
Thread.sleep();
-
线程礼让
yield();
让CPU重新调度线程,有可能礼让失败
-
线程强制执行
join();
强制执行该线程,知道该线程执行完毕,才执行其他线程(包括主线程)任务;导致线程阻塞,尽量不要使用;
-
同步方法及同步块(同步锁)
使用方法:
- 同步块:@synchronized(锁定对象)
- 同步方法:public synchronized void buy(){}
package com.phil.gui1; //模拟抢票 ---同步锁 public class TestThread implements Runnable { private int ticketNum = 10; @Override public void run() { while (true) { synchronized (this) { if (ticketNum <= 0) { break; } try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "抢到了第" + ticketNum-- + "张票"); } } } public static void main(String[] args) { TestThread testThread1 = new TestThread(); new Thread(testThread1, "小明").start(); new Thread(testThread1, "老师").start(); new Thread(testThread1, "爸爸").start(); } }
死锁
package com.phil.gui1;
public class DeadLockTest {
public static void main(String[] args) {
Mackup mackup1 = new Mackup(0, "白雪公主");
Mackup mackup2 = new Mackup(1, "灰姑娘");
mackup1.start();
mackup2.start();
}
}
//口红类
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class Mackup extends Thread{
//资源使用静态,保证只有一份
//口红
private static Lipstick lipstick = new Lipstick();
//镜子
private static Mirror mirror = new Mirror();
int choise;//选择 0-获取口红,1-获取镜子
String girlName;//使用此化妆品的人
Mackup(int choise, String girlName){
this.choise = choise;
this.girlName = girlName;
}
private void mackup() throws InterruptedException {
if (choise==0) {
synchronized (lipstick) {
System.out.println(this.girlName + "获得口红的锁");
Thread.sleep(1000);
//一秒后想要获得镜子的锁
synchronized (mirror) {
System.out.println(this.girlName + "获取镜子的锁");
}
}
}else {
synchronized (mirror) {
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(2000);
//2秒后,想要获得口红的锁
synchronized (lipstick) {
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}
@Override
public void run() {
//化妆
try {
mackup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 把延迟执行的synchronized相关代码块提取出来放在外层synchronized的外面执行,就能正常输出结果
Lock锁
package com.phil.gui1;
import com.sun.tools.javadoc.Start;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket).start();
new Thread(buyTicket).start();
new Thread(buyTicket).start();
}
}
class BuyTicket implements Runnable{
int ticket = 10;
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
if (ticket <= 0) {
break;
}
try {
Thread.sleep(1000);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("剩余票数" + ticket--);
lock.unlock();
}
}
}
多线程协作问题(消费者与生产者问题)
-
管程法
package com.phil.gui1; import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode; import java.lang.reflect.Constructor; //管程法 --- 解决 生产者/消费者问题 //生产鸡腿 鸡腿 消费鸡腿 容器 public class Consumer { public static void main(String[] args) { SynConstainer constainer = new SynConstainer(); new Thread(new Product(constainer)).start(); new Thread(new Customer(constainer)).start(); } } //鸡 class Chiken{ public int id; public Chiken(int id) { this.id = id; } } //生产者 class Product implements Runnable{ SynConstainer synConstainer; public Product(SynConstainer synConstainer) { this.synConstainer = synConstainer; } @Override public void run() { //生产 for (int i = 0; i < 100; i++) { Chiken chiken = new Chiken(i); this.synConstainer.push(chiken); System.out.println("生产了第" + i + "只鸡"); } } } //消费者 class Customer implements Runnable { SynConstainer synConstainer; public Customer(SynConstainer synConstainer) { this.synConstainer = synConstainer; } @Override public void run() { for (int i = 0; i < 100; i++) { // synConstainer.pop(); System.out.println("消费--->" + synConstainer.pop().id + "只鸡"); } } } //容器 class SynConstainer{ Chiken[] chikens = new Chiken[10]; int count; //生产 public synchronized void push(Chiken chiken) { //容器满了,等待消费者消费 if (count==chikens.length) { try { this.wait(); }catch (Exception e) { e.printStackTrace(); } } //没有满,填充鸡腿 chikens[count] = chiken; count++; //通知消费者消费 this.notifyAll(); } //消费 public synchronized Chiken pop(){ //没有鸡了,等待生产者生产 if (count==0) { try { this.wait(); }catch (Exception e) { e.printStackTrace(); } } //可以消费 count--; this.notifyAll(); return chikens[count]; } } -
信号灯法
通过标志位解决消费者生产者问题
package com.phil.gui1; //生产者消费者问题 --- 信号灯法 /** * 演员表演节目 观众观看 * 类:演员(Player)、观众(Audience)、容器(TV) */ public class ConsumerSign { public static void main(String[] args) { TV tv = new TV(); new Thread(new Player(tv)).start(); new Thread(new Audience(tv)).start(); } } class Player implements Runnable{ TV tv; public Player(TV tv) { this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { if (i%2==0) { try { tv.play("杂技"); } catch (InterruptedException e) { e.printStackTrace(); } }else { try { tv.play("广告"); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class Audience implements Runnable{ private TV tv; public Audience(TV tv) { this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { try { tv.watch(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class TV{ //表演内容 private String show; //是否表演 private Boolean flag = true; public synchronized void play(String show) throws InterruptedException { if (!flag) { this.wait(); } this.show = show; System.out.println("演员表演了" + show); //通知观众观看 this.notifyAll(); flag = !flag; } public synchronized void watch() throws InterruptedException { if (flag) this.wait(); System.out.println("观看了--->" + show); flag = !flag; //通知演员表演 this.notifyAll(); } }
线程池
package com.phil.gui1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//线程池学习
public class TestPool {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
service.submit(new MyThread());
service.submit(new MyThread());
service.submit(new MyThread());
service.submit(new MyThread());
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}

浙公网安备 33010602011771号