目录
解决方式1--并发协作模型 “ 生产者 / 消费者模式 ” --->管程法
解决方式2--并发协作模型 “ 生产者 / 消费者模式 ” --->信号灯法
简介
实现(重点)
Lamda表达式
示例1:依次简化
示例2:带参数的方法
示例3:在2的基础上简化
1.lamdba表达式只能简化有一行代码的情况,若有多行,则用代码块;
2.前提:接口为函数式接口
3.多个参数也可以化简,全部去掉参数类型,但是不能去掉括号
状态
停止线程
线程休眠
线程礼让
让当前正在执行的线程暂停,但不阻塞;将线程从运行状态转为就绪状态;
Join -- vip
Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞 --- 可以想象成插队
线程状态观测
package 多线程;
public class Text01 {
public static void main(String[] args) {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("lll");
});
//观察状态
Thread.State state = thread.getState();
System.out.println(state);
//观察启动后
thread.start();
state=thread.getState();
System.out.println(state);
while(state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
state=thread.getState();//更新线程状态
System.out.println(state);
}
}
}
//一旦进入死亡状态,就不能再次启动
/*
NEW
RUNNABLE
RUNNABLE
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
lll
TERMINATED
Process finished with exit code 0
*/
线程的优先级
package 多线程;
public class TextPriority {
public static void main(String[] args) {
//主线程默认优先级
System.out.println(Thread.currentThread().getName()+"---->"+Thread.currentThread().getPriority());
MyPriority myPriority = new MyPriority();
Thread thread1 = new Thread(myPriority);
Thread thread2 = new Thread(myPriority);
Thread thread3 = new Thread(myPriority);
Thread thread4 = new Thread(myPriority);
Thread thread5 = new Thread(myPriority);
//先设置优先级,再启动;优先级高的先跑
thread1.start();
thread2.setPriority(1);
thread2.start();
thread3.setPriority(Thread.MAX_PRIORITY);//10
thread3.start();
//thread4.setPriority(-1);报错
//thread5.setPriority(11);报错
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"---->"+Thread.currentThread().getPriority());
}
}
//main---->5
//Thread-2---->10
//Thread-0---->5
//Thread-1---->1
守护线程
package 多线程;
//A守护B
public class TextTameon {
public static void main(String[] args) {
A a = new A();
B b = new B();
Thread thread = new Thread(a);
thread.setDaemon(true);//默认false->用户线程
thread.start();//守护线程启动
new Thread(b).start();//用户线程启动
}
}
//A
class A implements Runnable{
@Override
public void run() {
while(true){
System.out.println("BBBBBBBBBBBBBBBB");
}
}
}
//B
class B implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("AAAAAAAAAAAAAA");
}
System.out.println("GoodBye");
}
}
线程同步
同个对象被多个线程同时操作--同步
多个线程访问同一个对象--并发
三大不安全案例
1
package 多线程;
//不安全的买票
public class UnSafeBuyTicket {
public static void main(String[] args) {
BuyTicket ticket = new BuyTicket();
new Thread(ticket,"1").start();
new Thread(ticket,"2").start();
new Thread(ticket,"3").start();
}
}
class BuyTicket implements Runnable {
//票
private int ticketNum = 50;
boolean flag = true;//外部停止方式
@Override
public void run() {
//买票
while(flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void buy() throws InterruptedException {
//判断是否有票
if (ticketNum <= 0) {
flag = false;
return;
}
//模拟延时
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "拿到" + ticketNum--);
}
}
2
package 多线程;
import static java.lang.Thread.currentThread;
public class UnSafeBank {
public static void main(String[] args) {
Account account = new Account(100,"jijin");
Drawing you = new Drawing(account, 50, "you");
Drawing i = new Drawing(account, 100, "I");
you.start();
i.start();
}
}
//账户
class Account {
int money;//余额
String name;//卡名
public Account(int money,String name) {
this.money = money;
this.name = name;
}
}
//银行:模拟取款
class Drawing extends Thread{
Account account;//账户
int drawingMoney;//取钱
int nowMoney;//剩钱
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account=account;
this.drawingMoney=drawingMoney;
}
//取钱
@Override
public void run() {
//判断现在有没有钱
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
return ;
}
//sleep放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money=account.money-drawingMoney;
nowMoney=nowMoney+drawingMoney;
System.out.println(account.name+"余额为"+account.money);
System.out.println(this.getName()+Thread.currentThread().getName()+"手里的钱"+nowMoney);
}
}
3
package 多线程;
import java.util.ArrayList;
import java.util.List;
//线程不安全的集合
public class UnsafeList {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
解决方法
1
package 多线程;
//不安全的买票
public class UnSafeBuyTicket {
public static void main(String[] args) {
BuyTicket ticket = new BuyTicket();
new Thread(ticket,"1").start();
new Thread(ticket,"2").start();
new Thread(ticket,"3").start();
}
}
class BuyTicket implements Runnable {
//票
private int ticketNum = 50;
boolean flag = true;//外部停止方式
@Override
public void run() {
//买票
while(flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//synchronized 同步方法,锁的是this
private synchronized void buy() throws InterruptedException {
//判断是否有票
if (ticketNum <= 0) {
flag = false;
return;
}
//模拟延时
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "拿到" + ticketNum--);
}
}
2
package 多线程;
import static java.lang.Thread.currentThread;
public class UnSafeBank {
public static void main(String[] args) {
Account account = new Account(100,"jijin");
Drawing you = new Drawing(account, 50, "you");
Drawing i = new Drawing(account, 100, "I");
you.start();
i.start();
}
}
//账户
class Account {
int money;//余额
String name;//卡名
public Account(int money,String name) {
this.money = money;
this.name = name;
}
}
//银行:模拟取款
class Drawing extends Thread{
Account account;//账户
int drawingMoney;//取钱
int nowMoney;//剩钱
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account=account;
this.drawingMoney=drawingMoney;
}
//取钱
@Override
public void run() {
synchronized (account){
//判断现在有没有钱
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
return ;
}
//sleep放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money=account.money-drawingMoney;
nowMoney=nowMoney+drawingMoney;
System.out.println(account.name+"余额为"+account.money);
System.out.println(this.getName()+Thread.currentThread().getName()+"手里的钱"+nowMoney);
}
}
}
3
for (int i = 0; i < 10000; i++) {
new Thread(()->{
synchronized (list){
list.add(Thread.currentThread().getName());
}
}).start();
}
死锁
package 多线程;
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0, "wang");
Makeup g2 = new Makeup(1, "zhang");
g1.start();
g2.start();
}
}
//口红
class Lispstick {
}
//镜子
class Mirror {
}
class Makeup extends Thread {
//需要的资源只有一份,用static来保证只有一份
static Lispstick lispstick = new Lispstick();
static Mirror mirror = new Mirror();
int choice;//选择
String girl;//使用化妆品的人
Makeup(int choice, String girl) {
this.choice = choice;
this.girl = girl;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//化妆:互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (choice == 0) {
synchronized (lispstick) {
//获得口红的锁
System.out.println(this.girl + "获得口红的锁");
Thread.sleep(1000);
synchronized (mirror) {//一秒钟后想获得镜子
System.out.println(this.girl + "获得镜子的锁");
}
}
} else {
synchronized (mirror) {
//获得mirror的锁
System.out.println(this.girl + "获得镜子的锁");
Thread.sleep(2000);
synchronized (lispstick) {//一秒钟后想获得口红
System.out.println(this.girl + "获得口红的锁");
}
}
}
}
}
处理方法:
//化妆:互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (choice == 0) {
synchronized (lispstick) {
//获得口红的锁
System.out.println(this.girl + "获得口红的锁");
Thread.sleep(1000);
}
synchronized (mirror) {//一秒钟后想获得镜子
System.out.println(this.girl + "获得镜子的锁");
}
} else {
synchronized (mirror) {
//获得mirror的锁
System.out.println(this.girl + "获得镜子的锁");
Thread.sleep(2000);
}
synchronized (lispstick) {//一秒钟后想获得口红
System.out.println(this.girl + "获得口红的锁");
}
}
}
Lock锁
package 多线程;
import java.util.concurrent.locks.ReentrantLock;
public class TextLOck {
public static void main(String[] args) {
TextLock2 textLock2 = new TextLock2();
new Thread(textLock2).start();
new Thread(textLock2).start();
new Thread(textLock2).start();//多个资源操纵同一个对象,不安全(出现-1)
}
}
class TextLock2 implements Runnable{
int ticketnum =10;
//定义lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
lock.lock();//加锁
if(ticketnum>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketnum--);
}else{
break;
}
}finally {
//解锁
lock.unlock();
}
}
}
}
线程协作模式
解决方式1--并发协作模型 “ 生产者 / 消费者模式 ” --->管程法
package 多线程;
//测试:生产者消费者模型--》利用缓冲区解决:管程法
//生产者,消费者,产品,缓冲区
public class TestPc {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
//生产者
class Productor extends Thread {
SynContainer container;
public Productor(SynContainer container) {
this.container = container;
}
//生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了" + i + "只鸡");
}
}
}
//消费者
class Consumer extends Thread {
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
//消费
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了-->" + container.pop().id + "只鸡");
}
}
}
//产品
class Chicken {
int id;//产品标号
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer {
//需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken) {
//如果容器满了,就需要等待消费者消费
if (count == chickens.length) {
//通知消费者消费,生产等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,丢入产品
chickens[count] = chicken;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop() {
//判断能否消费
if (count == 0) {
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果可以消费
count--;
Chicken chicken = chickens[count];
//通知生产者生产
this.notifyAll();
return chicken;
}
}
解决方式2--并发协作模型 “ 生产者 / 消费者模式 ” --->信号灯法
package 多线程;
//测试生产者消费者问题2:信号灯法:标志位解决
public class TextPC2 {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
//生产者--演员
class Player extends Thread{
TV tv;
public Player(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if(i%2==0){
this.tv.play("a");
}else {
this.tv.play("b");
}
}
}
}
//消费者--观众
class Watcher extends Thread{
TV tv;
public Watcher(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
//产品--节目
class TV{
//演员表演,观众等待 T
//观众观看,演员等待 F
String voice;//表演的节目
boolean flag = true;
//表演
public synchronized void play(String voice) {
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了:" + voice);
//通知观众观看
this.notifyAll();//通知唤醒
this.voice = voice;
this.flag = !this.flag;
}
//观看
public synchronized void watch(){
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观看了:"+voice);
//通知演员表演
this.notifyAll();//通知唤醒
this.flag = !this.flag;
}
}
使用线程池
package 多线程;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TextPllo {
public static void main(String[] args) {
//1。创建服务,创建线程池
//newFixedThreadPool 参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
//执行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭链接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
总结
package 多线程;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
//总结线程的创建
public class ThreadNew {
public static void main(String[] args) {
new MyThread1().start();
new Thread(new MyThread2()).start();
FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread3());
new Thread(futureTask).start();
try {
Integer integer = futureTask.get();
System.out.println(integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
//1.继承Thread类
class MyThread1 extends Thread{
@Override
public void run() {
System.out.println("MyThread1");
}
}
//2.实现Runnable接口
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("MyThread2");
}
}
//3。实现Callable接口
class MyThread3 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("MyThread3");
return 100;
}
}