多线程
1. 概述
- 程序是指令和数据的有序集合,是一个静态的概念
- 进程是执行程序的一次执行概念,是一个动态的概念
- 线程是CPU调度和执行的单位,一个进程至少有一个线程
2. Thread
2.1 创建线程
2.1.1 extends Thread
- 两条线程是并行交替执行
- 线程不一定立即执行
package demo01;
public class ThreadDemo01 extends Thread{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("I am coding..."+i);
}
}
public static void main(String[] args) {
//main线程,主线程
ThreadDemo01 threadDemo01 = new ThreadDemo01();
//利用start开启线程
threadDemo01.start();
for (int i = 0; i < 20; i++) {
System.out.println("I am learn Thread..."+i);
}
}
}
2.1.2 网图下载
package demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//download image
public class DownloderImage extends Thread{
private String url;
private String name;
public DownloderImage(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name+"的文件");
}
public static void main(String[] args) {
DownloderImage demo01 = new DownloderImage("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","1.jpg");
DownloderImage demo02 = new DownloderImage("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","2.jpg");
DownloderImage demo03 = new DownloderImage("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","3.jpg");
demo01.start();
demo02.start();
demo03.start();
}
}
class WebDownloader{
//下载方法
public void downloader(String url,String name){
try {
//把URL变成一个文件
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现异常");
}
}
}
2.1.3 implements Runnable
package demo01;
public class ThreadDemo02 implements Runnable{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("I am coding..."+i);
}
}
public static void main(String[] args) {
//main线程,主线程
ThreadDemo02 demo02 = new ThreadDemo02();
//通过线程来开启线程
new Thread(demo02).start();
for (int i = 0; i < 20; i++) {
System.out.println("I am learn Thread..."+i);
}
}
}
2.1.4 龟兔赛跑
package demo01;
//模拟龟兔赛跑
public class Race implements Runnable{
private static String winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
//模拟兔子休息
if (Thread.currentThread().getName().equals("兔子") && i>=50 && i%10==0){
try {
Thread.sleep(10);
} 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) {
Race race = new Race();
new Thread(race,"乌龟").start();
new Thread(race,"兔子").start();
}
}
2.1.5 implements Callable
package demo02;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
//download image
public class CallableDemo01 implements Callable {
private String url;
private String name;
public CallableDemo01(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public Boolean call() {
WebDownloader1 webDownloader = new WebDownloader1();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name+"的文件");
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableDemo01 demo01 = new CallableDemo01("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","1.jpg");
CallableDemo01 demo02 = new CallableDemo01("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","2.jpg");
CallableDemo01 demo03 = new CallableDemo01("https://images.cnblogs.com/cnblogs_com/blogs/783676/galleries/2335338/o_230812174934_bd.jpg","3.jpg");
//创建执行服务
ExecutorService es = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> result1 = es.submit(demo01);
Future<Boolean> result2 = es.submit(demo02);
Future<Boolean> result3 = es.submit(demo03);
//获取结果
Boolean b1 = result1.get();
Boolean b2 = result2.get();
Boolean b3 = result3.get();
//关闭服务
es.shutdown();
}
}
class WebDownloader1{
//下载方法
public void downloader(String url,String name){
try {
//把URL变成一个文件
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现异常");
}
}
}
2.2 静态代理模式
package demo03;
public class ProxyDemo01 {
public static void main(String[] args) {
Wedding wedding = new Wedding(new You());
wedding.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
//真实角色
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("马上要结婚了,开心");
}
}
//代理角色
class Wedding implements Marry{
private Marry target;
public Wedding(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();
after();
}
private void after() {
System.out.println("结婚之后,收尾款");
}
private void before() {
System.out.println("结婚之前,布置现场");
}
}
2.3 Lambda
- 简化代码
- 任何接口如果只包含唯一一个抽象方法,那么它就是一个函数式接口
package demo03;
public class LambdaDemo01 {
//2.静态内部类
static class Like2 implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda2");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
like=new Like2();
like.lambda();
//3.局部内部类
class Like3 implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda3");
}
}
like = new Like3();
like.lambda();
//4.匿名内部类
like = new ILike() {
@Override
public void lambda() {
System.out.println("I like lambda4");
}
};
like.lambda();
//5.lambda
like = ()-> {
System.out.println("I like lambda5");
};
like.lambda();
}
}
//函数式接口
interface ILike{
void lambda();
}
//1.实现类:成员内部类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda");
}
}
package demo03;
public class LambdaDemo02 {
public static void main(String[] args) {
ILove love = new Love();
love.love("quinn");
love = new ILove() {
@Override
public void love(String name) {
System.out.println(name+" love java");
}
};
love.love("morita");
//1. lambda简化
love = (String name)-> {
System.out.println(name+" love java");
};
love.love("Cx330");
//2. 去掉参数类型
love = (name)->{
System.out.println(name+" love java");
};
love.love("yq");
//3. 去掉()与{}:方法体只有一行
love = name -> System.out.println(name+" love java");
love.love("zy");
}
}
interface ILove{
void love(String name);
}
class Love implements ILove{
@Override
public void love(String name) {
System.out.println(name+" love java");
}
}
2.4 线程五大状态
- 创建状态
- 就绪状态
- 阻塞状态
- 运行状态
- 死亡状态
package demo05;
public class StatusDemo01 {
public static void main(String[] args) throws InterruptedException {
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);//NEW
thread.start();
state = thread.getState();
System.out.println(state);//RUN
while (state != Thread.State.TERMINATED){
Thread.sleep(100);
state = thread.getState();
System.out.println(state);
}
}
}
2.5 线程停止
package demo04;
//不建议使用stop或者destroy方法
public class StopDemo01 implements Runnable{
//set flag
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run.....Thread"+(i++));
}
}
//2. set stop method
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
StopDemo01 demo01 = new StopDemo01();
new Thread(demo01).start();
for (int i = 0;i < 1000;i++){
System.out.println("main"+i);
if (i == 500){
demo01.stop();
System.out.println("线程停止");
}
}
}
}
2.6 模拟延时
package demo04;
//模拟延时
public class SleepDemo01 implements Runnable{
private int ticketNums = 10;
@Override
public void run() {
while (true){
if (ticketNums <= 0){
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--->拿到了第"+(ticketNums--)+"票");
}
}
public static void main(String[] args) {
SleepDemo01 demo01 = new SleepDemo01();
new Thread(demo01,"小明").start();
new Thread(demo01,"小红").start();
new Thread(demo01,"小黄").start();
}
}
package demo04;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
public class SleepDemo02{
//模拟倒计时
public static void timeDown() throws Exception {
int num = 10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num <= 0){
break;
}
}
}
public static void main(String[] args) {
/*try {
timeDown();
} catch (Exception e) {
e.printStackTrace();
}*/
//打印系统当前时间
Date date = new Date(System.currentTimeMillis());
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
date = new Date(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.7 Yield:线程礼让
- 让当前正在执行的线程停止,但不阻塞
- 礼让不一定成功
package demo04;
public class YieldDemo01 {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"....start....");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"....stop.....");
}
}
2.8 Join:线程强制执行
package demo04;
public class JoinDemo01 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 300; i++) {
System.out.println("线程vip来了"+i);
}
}
public static void main(String[] args) throws Exception {
JoinDemo01 demo01 = new JoinDemo01();
Thread thread = new Thread(demo01);
thread.start();
for (int i = 0; i < 500; i++) {
if (i == 100){
thread.join();//插队
}
System.out.println("main:"+i);
}
}
}
2.9 线程优先级
package demo05;
//测试线程优先级
//1-10
public class PriorityDemo01 {
public static void main(String[] args) {
//主线程优先级
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
MyPriority priority = new MyPriority();
Thread thread1 = new Thread(priority);
Thread thread2 = new Thread(priority);
Thread thread3 = new Thread(priority);
Thread thread4 = new Thread(priority);
//先设置优先级在启动
thread1.start();
thread2.setPriority(1);
thread2.start();
thread3.setPriority(4);
thread3.start();
thread4.setPriority(Thread.MAX_PRIORITY);
thread4.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
2.10 守护线程
- 线程分为用户线程和守护线程
package demo05;
public class DaemonDemo01 {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread t1 = new Thread(god);
t1.setDaemon(true);//默认false为用户线程
t1.start();
new Thread(you).start();
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心的活着");
}
System.out.println("=======goodbye!==========");
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保护你");
}
}
}
3. 线程同步
- 多线程操作同一个资源
4. 死锁
4.1 产生条件
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对方已获得的资源保持不放
- 不剥夺条件:进程已获得的资源在未使用完之前不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
package demo07;
public class DeadLockDemo01 {
public static void main(String[] args) {
Makeup m1 = new Makeup(0,"lisa");
Makeup m2 = new Makeup(1,"lily");
m1.start();
m2.start();
}
}
class Lipstick{
}
class Mirror{
}
class Makeup extends Thread{
//static保证需要的资源只有一份
static Lipstick lip = new Lipstick();
static Mirror mi = 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();
}
}
private void makeup() throws InterruptedException {
if (choice == 0){
synchronized (lip){
System.out.println(this.girlName+"获得口红的锁");
sleep(1000);
synchronized (mi){
System.out.println(this.girlName+"获得镜子的锁");
}
}
}else {
synchronized (mi){
System.out.println(this.girlName+"获得镜子的锁");
sleep(2000);
}
synchronized (lip){
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
5. 锁
package demo07;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo01 {
public static void main(String[] args) {
TestClock testClock = new TestClock();
new Thread(testClock).start();
new Thread(testClock).start();
new Thread(testClock).start();
}
}
class TestClock implements Runnable{
int tickNums = 10;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try {
//加锁
lock.lock();
if (tickNums > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tickNums--);
} else {
break;
}
}finally {
//解锁
lock.unlock();
}
}
}
}
6. 生产者消费者问题
6.1 管程法
package demo08;
//测试生产者消费者模型-->利用缓冲区解决:管程法
public class PCDemo01 {
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++) {
System.out.println("生产了"+i+"只鸡");
container.push(new Chicken(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 fill,wait product
if (count == chickens.length){
try {
//消费者等待
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//if not fill,push chicken
chickens[count] = chicken;
count++;
//通知消费者消费
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//is pop?
if (count == 0){
//wait push
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
Chicken chicken = chickens[count];
this.notifyAll();
//通知生产者生产
return chicken;
}
}
6.2 信号灯法
package demo08;
import org.omg.CORBA.TCKind;
//信号灯法:flag
public class PCDemo02 {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
//productor-->演员
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("《快乐大本营》播放中");
}else {
this.tv.play("广告播放中");
}
}
}
}
//consumer-->观众
class Watcher extends Thread{
TV tv;
public Watcher(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
this.tv.watch();
}
}
}
//product-->节目
class TV {
//player playing,watcher wait
String voice;//表演的节目
boolean flag = true;//player playing
public synchronized void play(String voice){
if (flag == false){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了:"+voice);
this.voice = voice;
this.notifyAll();
this.flag = !this.flag;
}
//watcher watching,player wait
public synchronized void watch(){
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观众观看了:"+voice);
this.notifyAll();
this.flag = !this.flag;
}
}
7. 线程池
package demo09;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolDemo01 {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(10);
pool.execute(new MyThread());
pool.execute(new MyThread());
pool.execute(new MyThread());
pool.execute(new MyThread());
pool.execute(new MyThread());
pool.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
标签:Thread,void,println,new,多线程,public,out
From: https://www.cnblogs.com/yqquinn/p/17628331.html