文章目录
一、线程的创建(继承Thread类)
package chap3;
/*
创建线程
1、自定义线程类继承Thread
2、重写run方法,编写线程执行体
3、创建线程对象,调用start启动线程
线程开启不一定立即执行
*/
public class Demo1 extends Thread{
@Override
public void run() {
for (int i=0;i<20;i++){
System.out.println("我在看代码++"+i);
}
}
public static void main(String[] args) {
Demo1 demo1=new Demo1();
demo1.start();
for (int i=0;i<20;i++){
System.out.println("我在看代码--"+i);
}
}
}
二、多线程下载图片
package chap1;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class Demo1 extends Thread{
private String url;
private String name;
public Demo1(String url,String name){
this.url=url;
this.name=name;
}
public static void main(String[] args) {
Demo1 demo1=new Demo1("https://tse1-mm.cn.bing.net/th/id/OIP-C.QFdwl07_aviM1ch2KpyyFgHaEo?pid=ImgDet&rs=1",
"风景1.jpg");
Demo1 demo2=new Demo1("https://tse2-mm.cn.bing.net/th/id/OIP-C.n0_p3rYRuofABd3XudbZnAHaEo?pid=ImgDet&rs=1",
"风景2.jpg");
Demo1 demo3=new Demo1("https://pic3.zhimg.com/v2-58d652598269710fa67ec8d1c88d8f03_r.jpg?source=1940ef5c",
"风景3.jpg");
demo1.start();
demo2.start();
demo3.start();
}
@Override
public void run() {
WebDownLoader webDownLoader=new WebDownLoader();
webDownLoader.downloader(url,name);
System.out.println("下载的文件名为:"+name);
}
}
class WebDownLoader{
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
三、线程的创建(Runable方法)
package chap1;
public class Demo2 implements Runnable{
@Override
public void run() {
for (int i=0;i<20;i++){
System.out.println("我在看代码++"+i);
}
}
public static void main(String[] args) {
Demo2 demo2=new Demo2();
new Thread(demo2).start();
for (int i=0;i<20;i++){
System.out.println("我在看代码--"+i);
}
}
}
四、实例:龟兔赛跑
public class RacingGameDemo implements Runnable{
private static String winner;
@Override
public void run() {
for (int i=0;i<=100;i++){
// 模拟兔子休息
if (Thread.currentThread().getName()=="兔子"){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boolean flag=gameOver(i);
if (flag){
break;
}
System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
}
}
private boolean gameOver(int steps){
if (winner!=null){
return true;
}else {
if (steps>=100){
winner=Thread.currentThread().getName();
System.out.println("winner is "+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
RacingGameDemo racingGameDemo=new RacingGameDemo();
new Thread(racingGameDemo,"乌龟").start();
new Thread(racingGameDemo,"兔子").start();
}
}
五、创建线程(Callable)
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
/*
Callable接口实现多线程
需要有返回值
重写call需要抛出异常
创建目标对象
创建执行服务 ExecutorService service= Executors.newFixedThreadPool(1);
提交执行 Future<Boolean> result=ser.submit(1)
获取结果 boolean r1=result.get()
关闭服务 ser.shutdownNow()
*/
public class CallableDemo implements Callable {
private String url;
private String name;
public CallableDemo(String url,String name){
this.url=url;
this.name=name;
}
@Override
public Boolean call() throws Exception {
WebDownLoader webDownLoader=new WebDownLoader();
webDownLoader.downloader(url,name);
System.out.println("下载的文件名为:"+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableDemo demo1=new CallableDemo("https://tse1-mm.cn.bing.net/th/id/OIP-C.QFdwl07_aviM1ch2KpyyFgHaEo?pid=ImgDet&rs=1",
"风景1.jpg");
CallableDemo demo2=new CallableDemo("https://tse2-mm.cn.bing.net/th/id/OIP-C.n0_p3rYRuofABd3XudbZnAHaEo?pid=ImgDet&rs=1",
"风景2.jpg");
CallableDemo demo3=new CallableDemo("https://pic3.zhimg.com/v2-58d652598269710fa67ec8d1c88d8f03_r.jpg?source=1940ef5c",
"风景3.jpg");
// 创建执行服务
ExecutorService service= Executors.newFixedThreadPool(3);
// 提交执行
Future<Boolean> r1=service.submit(demo1);
Future<Boolean> r2=service.submit(demo2);
Future<Boolean> r3=service.submit(demo3);
// 获取结果
boolean rs1=r1.get();
boolean rs2=r2.get();
boolean rs3=r3.get();
// 关闭服务
service.shutdownNow();
}
}
class WebDownLoader{
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
六、静态代理模式
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色
好处:
代理对象可以做好多真实对象做不了的事情
真实对象就专注做自己的事情
在多线程中 Thread类代理Runable接口
public class StaticAgentDemo {
public static void main(String[] args) {
WeddingCompany weddingCompany=new WeddingCompany(new You());
weddingCompany.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("Happy to marry");
}
}
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry marry){
this.target=marry;
}
@Override
public void HappyMarry() {
before();
target.HappyMarry();
after();
}
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
}
七、lamda表达式
目的是为了简化代码
()->代码块
lamda表达式
1、避免匿名内部类定义过多
2、可以让你的代码看起来简洁
3、去掉了一堆没有意义的代码,只留下核心的逻辑
任何接口只包含一个方法,则是函数式接口
对于函数式接口,则可以用lamda表达式创建接口对象
内部类 写在类的外层
静态内部类 写在类内
局部内部类 写在main内
匿名内部类 没有类的名称,必须借助接口或父类
public class LamdaDemo {
public static void main(String[] args) {
ILike like=new Like();
// 匿名内部类
like= new ILike() {
@Override
public void lamda(int a) {
System.out.println("lamda4"+a);
}
};
like.lamda(66);
// lamda表达式简化
like=(int a)->{
System.out.println("lamda5"+a);
};
like.lamda(66);
// 简化去掉括号
like=b->{System.out.println("lamda5"+b);};
like.lamda(67);
// 简化去掉花括号
like=c-> System.out.println("lamda5"+c);
like.lamda(68);
// lamda表达式 只能有一行代码才可以用,有多行要用代码块 接口要为函数式接口
}
}
interface ILike{
void lamda(int a);
}
class Like implements ILike{
@Override
public void lamda(int a) {
System.out.println("I like lamda");
}
}
八、线程的停止
import javafx.scene.paint.Stop;
/*
setPriority(int newPriority) 更改线程的优先级
static void sleep(long millis) 在指定的时间内让当前正在执行的线程休眠
void join() 等待该线程停止
static void yield() 暂停当前正在执行的线程对象,并执行其他线程
void interrupt() 中断线程,
boolean isAlive() 测试线程是否处于活动状态
*/
public class ThreadDemo2 implements Runnable{
// 设置一个公开的方法停止线程,转换标志位
public void stop(){
this.flag=false;
}
// 设置一个标志位
private boolean flag=true;
@Override
public void run() {
int i =0;
while (flag==true){
System.out.println("run...Thread"+i++);
}
}
public static void main(String[] args) {
ThreadDemo2 threadDemo2=new ThreadDemo2();
new Thread(threadDemo2).start();
for (int i=0;i<100000;i++){
// System.out.println("main"+i);
if (i==90000){
threadDemo2.stop();
System.out.println("线程停止了");
}
}
}
}
九、线程休眠
import java.text.SimpleDateFormat;
import java.util.Date;
public class SleepDemo {
public static void main(String[] args) {
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void tenDown() throws InterruptedException {
int num=10;
while (true){
Thread.sleep(1000);
num--;
Date starttime=new Date(System.currentTimeMillis());
System.out.println(new SimpleDateFormat("HH:mm:ss").format(starttime));
if (num==0){
break;
}
}
}
}
十、线程礼让
让当前执行的线程暂停,但是不阻塞
运行态转为就绪状态
public class YieldDemo implements Runnable{
public static void main(String[] args) {
YieldDemo yieldDemo=new YieldDemo();
new Thread(yieldDemo,"a").start();
new Thread(yieldDemo,"b").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"结束");
}
}
十一、线程强制执行join
Join合并线程,等待线程执行完成后再执行其他线程,其他线程阻塞(霸道插队)
public class JoinDemo implements Runnable{
public static void main(String[] args) throws InterruptedException {
JoinDemo joinDemo=new JoinDemo();
Thread thread=new Thread(joinDemo);
thread.start();
for (int i = 0; i < 500; i++) {
if (i==200){
thread.join();
}
System.out.println("main"+i);
}
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程VIP来了"+i);
}
}
}
十二、五大状态的观测
/*
线程的五大状态
NEW
RUNNABLE
BLOCKED
WAITING 正在等待另一线程执行特定动作
TIMED_WAITING 等待另一线程执行动作达到指定时间
TERMINATED 已退出线程
*/
public class ThreadState {
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("//");
}
);
Thread.State state=thread.getState();
System.out.println(state);
thread.start();
state=thread.getState();
System.out.println(state);
}
}
十三、线程的优先级
/*
默认优先级 5
*/
public class PriorityDemo {
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(4);
thread3.start();
thread4.setPriority(Thread.MAX_PRIORITY);
thread4.start();
thread5.setPriority(11);
thread5.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+
Thread.currentThread().getPriority());
}
}
十四、守护线程
/*
线程分为 用户线程和守护线程
虚拟机需要保证用户线程执行完毕
但是不需要保证守护线程执行完毕
*/
public class DaemonDemo {
public static void main(String[] args) {
God god=new God();
You1 you1=new You1();
Thread thread=new Thread(god);
thread.setDaemon(true);//设置为用户线程的守护线程
thread.start();
new Thread(you1).start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("I bless you");
}
}
}
class You1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("I am live");
}
System.out.println("Goodbye");
}
}
十五、线程的同步
并发:一个或多个同时运行
队列+锁保证线程的安全性
同步关键字 synchronized
synchronized 修饰 锁的是this对象
synchronized(可以锁任何方法){}
十六、死锁
模拟死锁
public class DeadLockDemo {
public static void main(String[] args) {
Makeup g1=new Makeup(0,"灰姑娘");
Makeup g2=new Makeup(1,"白雪公主");
g1.start();
g2.start();
}
}
class Lipstick{
}
class Mirror{
}
class Makeup extends Thread{
static Lipstick lipstick=new Lipstick();
static Mirror mirror=new Mirror();
int choice;
String girlname;
public Makeup(int choice, String girlname) {
this.choice = choice;
this.girlname = girlname;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void makeup() throws InterruptedException {
if (choice==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);
synchronized (lipstick){
System.out.println(this.girlname+"获得口红的锁");
}
}
}
}
}
解决死锁
public class DeadLockDemo {
public static void main(String[] args) {
Makeup g1=new Makeup(0,"灰姑娘");
Makeup g2=new Makeup(1,"白雪公主");
g1.start();
g2.start();
}
}
class Lipstick{
}
class Mirror{
}
class Makeup extends Thread{
static Lipstick lipstick=new Lipstick();
static Mirror mirror=new Mirror();
int choice;
String girlname;
public Makeup(int choice, String girlname) {
this.choice = choice;
this.girlname = girlname;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void makeup() throws InterruptedException {
if (choice==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);
}
synchronized (lipstick){
System.out.println(this.girlname+"获得口红的锁");
}
}
}
}
十七、锁(LOCK)
import java.util.concurrent.locks.ReentrantLock;
/*
Lock是显式锁,需要手动开关
synchronized是隐式锁,出了作用域自动释放
Lock只能锁代码块,synchronized有代码块锁和方法锁
用Lock锁 JVM花的时间少,性能更好,拓展性也好。
优先使用顺序
Lock>同步代码块>同步方法
*/
public class LockDemo {
public static void main(String[] args) {
Mylock mylock=new Mylock();
new Thread(mylock).start();
new Thread(mylock).start();
new Thread(mylock).start();
}
}
class Mylock implements Runnable{
int ticketnum=10;
// 定义lock锁 ReentrantLock可重复锁
private final ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
lock.lock();
try {
while (true){
if (ticketnum>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketnum--);
}else {
break;
}
}
}finally {
lock.unlock();
}
}
}
十八、生产者消费者问题(利用管程实现)
public class PCDemo {
public static void main(String[] args) {
SynContainer synContainer=new SynContainer();
new Productor(synContainer).start();
new Consumer(synContainer).start();
}
}
class Productor extends Thread{
SynContainer synContainer;
public Productor(SynContainer synContainer) {
this.synContainer = synContainer;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("生产了"+i+"只鸡");
synContainer.push(new Chichen(i));
}
}
}
class Consumer extends Thread{
SynContainer synContainer;
public Consumer(SynContainer synContainer) {
this.synContainer = synContainer;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了->"+synContainer.pop().id);
}
}
}
class Chichen{
int id;
public Chichen(int id) {
this.id = id;
}
}
class SynContainer{
// 需要一个容器大小
Chichen[] chichens=new Chichen[10];
// 容量计数器
int count= 0;
// 生产者放入产品
public synchronized void push(Chichen chichen){
// 容器满了就需要等待消费者
if (count==chichens.length){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 容器没有满,就丢入产品
chichens[count++]=chichen;
this.notifyAll();
}
// 消费者消费产品
public synchronized Chichen pop(){
// 判断能否消费
if (count==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
Chichen chichen=chichens[count];
// 吃完了,通知生产者生产
this.notifyAll();
return chichen;
}
}
十九、生产者消费者问题(信号灯解决)
/*
wait() 表示线程一直等待,直到其他线程通知
wait(long timeout) 指定等待的时间
notify() 唤醒一个处于等待中的进程
notifyAll() 唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度
*/
public class PCDemo2 {
public static void main(String[] args) {
TV tv =new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
class Player extends Thread{
TV tv=new 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.paly("快乐大本营播放了");
}else {
this.tv.paly("抖音记录美好生活");
}
}
}
}
class Watcher extends Thread{
TV tv=new TV();
public Watcher(TV tv) {
this.tv = tv;
for (int i = 0; i < 20; i++) {
this.tv.watch();
}
}
}
class TV{
String voice;
boolean flag=true;
public synchronized void paly(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;
}
}
二十、线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
线程池
ExecutorService和Executors两个接口
ExecutorService真正的线程池接口,常见子类ThreadPoolExecutor
execute(Runnable command) 执行命令,没有返回值,用来执行Runnable
Future submit 执行任务,有返回值,一般用来执行Callable
shutdown() 关闭连接池
Executors 工具类、线程池的工厂类,用于创建并返回不同类型的线程池
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService service= Executors.newFixedThreadPool(10);
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());
}
}