Java进阶04多线程
Java进阶04多线程
概述







线程创建

Thread类

package com.mingmao.multithreading.thread;
//创建线程方法一,继承Thread类,重写run()方法,调用start开启线程
public class TestThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("这是run线程,我在写代码----"+i);
}
}
public static void main(String[] args) {
TestThread testThread=new TestThread();
//testThread.run();//单线程,先执行完run()线程再继续往下执行
testThread.start(); //两条线程随机交替执行,cpu调度的,每次执行都不一样
for (int i = 0; i < 20; i++) {
System.out.println("这是主线程,我在看书-----"+i);
}
}
}
练习 多线程下载图片
使用jar包
1.下载jar包
commons.io 下载地址
2.copy jar包到IEDA








多线程下载图片
package com.mingmao.multithreading.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
public class DownloadPictures extends Thread{
private String url;//网络图片地址
private String filename;//保存的文件名
public DownloadPictures(String url,String filename){
this.url=url;
this.filename=filename;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,filename);
System.out.println("已下载文件"+filename);
}
public static void main(String[] args) {
DownloadPictures downloadPictures1=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150234451-1160669624.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\1.jpg");
DownloadPictures downloadPictures2=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150422206-2042991969.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\2.jpg");
DownloadPictures downloadPictures3=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150704087-1931814188.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\3.jpg");
downloadPictures1.start();
downloadPictures2.start();
downloadPictures3.start();
}
}
//下载器
class WebDownloader{
//下载方法
public void downloader(String url,String filename){
try {
FileUtils.copyURLToFile(new URL(url),new File(filename));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
} finally {
}
}
}
Runnable接口

package com.mingmao.multithreading.runnable;
//创建线程方式2,实现Runnable接口,重写run()方法,执行线程要丢入Runnable接口实现类,调用start()方法
public class TestRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("这是run线程,我在看代码----"+i);
}
}
public static void main(String[] args) {
TestRunnable testRunnable=new TestRunnable();
new Thread(testRunnable).start();
for (int i = 0; i < 20; i++) {
System.out.println("这是主线程,我在看书-----"+i);
}
}
}

初识并发问题
package com.mingmao.multithreading.concurrencyproblem;
//多个线程同时操作同一个对象--买火车票
public class TestConcurrency implements Runnable {
private int ticketNums=10;
@Override
public void run() {
while (true){
if(ticketNums<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
//延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
}
public static void main(String[] args) {
TestConcurrency testConcurrency=new TestConcurrency();
new Thread(testConcurrency,"小明").start();
new Thread(testConcurrency,"小红").start();
new Thread(testConcurrency,"小丽").start();
/*
小丽拿到了第10张票
小明拿到了第10张票
小红拿到了第9张票
小红拿到了第8张票
小明拿到了第7张票
小丽拿到了第6张票
小明拿到了第5张票
小红拿到了第3张票
小丽拿到了第4张票
小红拿到了第2张票
小明拿到了第2张票
小丽拿到了第1张票
*/
//问题,票拿重复了,多线程操作同一资源,线程不安全,数据紊乱
}
}
练习 龟兔赛跑

package com.mingmao.multithreading.concurrencyproblem;
//模拟龟兔赛跑
public class TortoiseAndRabbitRace implements Runnable{
private static String winner;
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
//模拟兔子休息 兔子每跑10步休息10ms
if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
boolean b=gameOver(i);
if(b){
break;
}else{
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
}
}
}
//判断是否完成比赛
private boolean gameOver(int steps){
if(winner!=null){return true;}
if(steps==100){
winner=Thread.currentThread().getName();
System.out.println("winner is "+winner);
return true;
}
return false;
}
public static void main(String[] args) {
TortoiseAndRabbitRace tortoiseAndRabbitRace=new TortoiseAndRabbitRace();
new Thread(tortoiseAndRabbitRace,"兔子").start();
new Thread(tortoiseAndRabbitRace,"乌龟").start();
}
}
Callable接口

package com.mingmao.multithreading.callable;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
//多线程创建方式三:实现Callable接口 以下载图片为例
public class TestCallable implements Callable {
private String url;
private String filename;
public TestCallable(String url,String filename){
this.url=url;
this.filename=filename;
}
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,filename);
System.out.println("已下载图片"+filename);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable testCallable1=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150234451-1160669624.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\4.jpg");
TestCallable testCallable2=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150422206-2042991969.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\5.jpg");
TestCallable testCallable3=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150704087-1931814188.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\6.jpg");
//创建执行服务
ExecutorService executorService= Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> future1=executorService.submit(testCallable1);
Future<Boolean> future2=executorService.submit(testCallable2);
Future<Boolean> future3=executorService.submit(testCallable3);
//获取结果
boolean b1=future1.get();
boolean b2=future2.get();
boolean b3=future3.get();
//关闭服务
executorService.shutdownNow();
}
}
//下载器
class WebDownloader{
public void downloader(String url,String filrname){
try {
FileUtils.copyURLToFile(new URL(url),new File(filrname));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
} finally {
}
}
}
静态代理模式

package com.mingmao.multithreading.staticproxy;
/*
静态代理模式:
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色,传递给代理对象一个参数
代理对象可以做很多真是对象做不了的事情
真是对象就专注做自己的事情
*/
public class TestStaticProxy {
public static void main(String[] args) {
//WeddingCompany weddingCompany=new WeddingCompany(new You());//丢入的是接口Marry的实现类
//weddingCompany.happyMarry();
new WeddingCompany(new You()).happyMarry();
}
}
interface Marry{
void happyMarry();
}
//真实角色,你去结婚
class You implements Marry{
@Override
public void happyMarry() {
System.out.println("祝贺结婚!");
}
}
//代理角色,帮助你结婚
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(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("结婚之前,布置现场");
}
}
Lambda表达式



package com.mingmao.multithreading.lambda;
//推导Lambda表达式
//原来的做法
public class TestLambda {
public static void main(String[] args) {
ILike iLike=new Like();
iLike.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
//实现类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda.");
}
}
package com.mingmao.multithreading.lambda;
//推导Lambda表达式
//静态内部类
public class TestLambda {
//静态内部类
static class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda.");
}
}
public static void main(String[] args) {
ILike iLike=new Like();
iLike.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
package com.mingmao.multithreading.lambda;
//推导Lambda表达式
//局部内部类
public class TestLambda {
public static void main(String[] args) {
class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda.");
}
}
ILike iLike=new Like();
iLike.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
package com.mingmao.multithreading.lambda;
//推导Lambda表达式
//匿名内部类
public class TestLambda {
public static void main(String[] args) {
//匿名内部类,没有类的名称,必须借助接口或者父类
new ILike(){
@Override
public void lambda() {
System.out.println("I like lambda.");
}
}.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
package com.mingmao.multithreading.lambda;
//推导Lambda表达式
//用lambda简化
public class TestLambda {
public static void main(String[] args) {
ILike iLike=() -> {
System.out.println("I like lambda.");
};
iLike.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
//带参数的接口
public class TestLambda2 {
public static void main(String[] args) {
ILove iLove=(i)->{
System.out.println("I love you "+i);
};
iLove.love(5);
}
}
interface ILove{
void love(int i);
}
package com.mingmao.multithreading.lambda;
//带参数的接口
public class TestLambda2 {
public static void main(String[] args) {
//只有一行代码可以简化括号,如果有多行代码,必须用代码块包裹
ILove iLove=i-> System.out.println("I love you "+i);
iLove.love(5);
}
}
interface ILove{
void love(int i);
}
线程状态及常用方法



停止线程stop

package com.mingmao.multithreading.commonmethod;
/*
测试stop:
1、建议线程正常停止--利用次数,不建议死循环
2、建议使用标志位--设置一个标志位
3、不要使用stop或者destroy等过时或者JDK不建议使用的方法
*/
public class TestStop implements Runnable{
private boolean flag=true;
@Override
public void run() {
int i=0;
while (flag){
System.out.println("run-----"+i++);
}
}
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
TestStop testStop=new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if(i==900){
testStop.stop();
System.out.println("线程run停止了");
}
}
}
}
线程休眠 sleep

package com.mingmao.multithreading.commonmethod;
//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable {
private int ticketNums=10;
private boolean flag=true;
@Override
public void run() {
while (flag){
if(ticketNums<=0){
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNums--+"张票");
}
}
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
TestSleep testSleep=new TestSleep();
new Thread(testSleep,"小明").start();
new Thread(testSleep,"小红").start();
new Thread(testSleep,"小丽").start();
}
}
package com.mingmao.multithreading.commonmethod;
//模拟倒计时
public class TestSleep2{
private int time=10;
public void countDown() {
while (true){
if(time<0){
break;
}
System.out.println("倒计时:"+time--);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
}
public static void main(String[] args) {
TestSleep2 testSleep2=new TestSleep2();
testSleep2.countDown();
}
}
线程礼让 yield

package com.mingmao.multithreading.commonmethod;
//礼让不一定成功,只是让CPU重新调度
public class TestYield {
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()+"线程开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"线程结束");
}
}
线程强制执行join

package com.mingmao.multithreading.commonmethod;
//强行插队
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程vip来了--"+i);
}
}
public static void main(String[] args) {
TestJoin testJoin=new TestJoin();
Thread thread=new Thread(testJoin);
thread.start();
for (int i = 0; i < 1000; i++) {
if(i==200){
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
System.out.println("main线程--"+i);
}
}
}
观测线程状态State

package com.mingmao.multithreading.commonmethod;
//观察测试线程的状态
//运行完之后的线程不能再次启动
public class TestState{
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();
} finally {
}
System.out.println("/////"+i);
}
});
Thread.State state = thread.getState();
System.out.println(state);//NEW
thread.start();
state = thread.getState();
System.out.println(state);//RUNNABLE
while (state!=Thread.State.TERMINATED){//如果线程没有终止,便持续输出线程状态
Thread.sleep(100);
state=thread.getState();
System.out.println(state);//TIMED_WAITING
}
}
}
线程的优先级Priority

package com.mingmao.multithreading.commonmethod;
public class TestPriority {
public static void main(String[] args) {
System.out.println("主线程默认优先级为:"+Thread.currentThread().getName()+"--"+Thread.currentThread().getPriority());
//主线程默认优先级为:main--5
MyPriority myPriority=new MyPriority();
Thread thread1=new Thread(myPriority,"线程1");
Thread thread2=new Thread(myPriority,"线程2");
Thread thread3=new Thread(myPriority,"线程3");
Thread thread4=new Thread(myPriority,"线程4");
Thread thread5=new Thread(myPriority,"线程5");
Thread thread6=new Thread(myPriority,"线程6");
//先设置优先级,再启动 1--慢,10-快
thread1.start();
thread2.setPriority(1);
thread2.start();
thread3.setPriority(4);
thread3.start();
thread4.setPriority(Thread.MAX_PRIORITY);
thread4.start();
thread5.setPriority(Thread.MIN_PRIORITY);
thread5.start();
thread6.setPriority(7);
thread6.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--"+Thread.currentThread().getPriority());
}
}
守护线程

package com.mingmao.multithreading.commonmethod;
//测试守护线程 上帝守护你
public class TestDaemonThread {
public static void main(String[] args) {
You you=new You();
God god=new God();
Thread thread=new Thread(god);
Thread thread1=new Thread(you);
thread.setDaemon(true);//默认是false,表示是用户线程
thread.start();//上帝守护线程启动
thread1.start();
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心的活着"+i);
}
System.out.println("===goodbye world!===");
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保佑着你");
}
}
}
线程同步




三大不安全案例
package com.mingmao.multithreading.synchronization;
//不安全的买票
//线程不安全,有负数
public class UnsafeTicketBuying implements Runnable {
private int ticketNums=10;
private boolean flag=true;
@Override
public void run() {
while (flag){
buy();
}
}
public void buy(){
if(ticketNums<=0){
flag=false;
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
}
public static void main(String[] args) {
UnsafeTicketBuying unsafeTicketBuying=new UnsafeTicketBuying();
new Thread(unsafeTicketBuying,"小明").start();
new Thread(unsafeTicketBuying,"小红").start();
new Thread(unsafeTicketBuying,"小丽").start();
}
}
package com.mingmao.multithreading.synchronization;
//不安全的取钱
//存款出现负数
public class UnsafeBank {
public static void main(String[] args) {
Account account=new Account(500,"家庭存款");
WithdrawMoney withdrawMoney=new WithdrawMoney(account,300,"小明");
WithdrawMoney withdrawMoney1=new WithdrawMoney(account,500,"小明的老婆");
withdrawMoney.start();
withdrawMoney1.start();
}
}
class Account{
int money;//余额
String name;//卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
class WithdrawMoney extends Thread{
Account account;
int drawMoney;//取的钱数
int nowMoney;//手中的钱
public WithdrawMoney(Account account,int drawMoney,String name){
super(name);
this.account=account;
this.drawMoney=drawMoney;
}
@Override
public void run() {
if((account.money-drawMoney)<0){
System.out.println(Thread.currentThread().getName()+"你的卡中余额不足");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
account.money-=drawMoney;
nowMoney+=drawMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱为:"+nowMoney);
}
}
package com.mingmao.multithreading.synchronization;
import java.util.ArrayList;
import java.util.List;
//不安全的线程
public class UnsafeList {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(list.size());//实际大小不是10000,线程不安全
}
}
同步方法及同步块



锁住需要增删改的对象,注意锁的范围太大锁就会无效,比如100个人排队上厕所,把100个人全部锁在厕所里,锁就无效,只锁一个人锁才有效
同步方法:
package com.mingmao.multithreading.synchronizationmethod;
public class UnsafeTicketBuying implements Runnable {
private int ticketNums=10;
private boolean flag=true;
@Override
public void run() {
while (flag){
buy();
}
}
public synchronized void buy(){
if(ticketNums<=0){
flag=false;
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
}
public static void main(String[] args) {
UnsafeTicketBuying unsafeTicketBuying=new UnsafeTicketBuying();
new Thread(unsafeTicketBuying,"小明").start();
new Thread(unsafeTicketBuying,"小红").start();
new Thread(unsafeTicketBuying,"小丽").start();
}
}
同步块:
package com.mingmao.multithreading.synchronizationmethod;
public class UnsafeBank {
public static void main(String[] args) {
Account account=new Account(500,"家庭存款");
WithdrawMoney withdrawMoney=new WithdrawMoney(account,300,"小明");
WithdrawMoney withdrawMoney1=new WithdrawMoney(account,500,"小明的老婆");
withdrawMoney.start();
withdrawMoney1.start();
}
}
class Account{
int money;//余额
String name;//卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
class WithdrawMoney extends Thread{
Account account;
int drawMoney;//取的钱数
int nowMoney;//手中的钱
public WithdrawMoney(Account account, int drawMoney, String name){
super(name);
this.account=account;
this.drawMoney=drawMoney;
}
@Override
public void run() {
synchronized (account){
if((account.money-drawMoney)<0){
System.out.println(Thread.currentThread().getName()+"你的卡中余额不足");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
account.money-=drawMoney;
nowMoney+=drawMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱为:"+nowMoney);
}
}
}
package com.mingmao.multithreading.synchronizationmethod;
import java.util.ArrayList;
import java.util.List;
public class UnsafeList {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
synchronized (list){
list.add(Thread.currentThread().getName());
}
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(list.size());
}
}
CopyOnWriteArrayList
package com.mingmao.multithreading.synchronizationmethod;
import java.util.concurrent.CopyOnWriteArrayList;
//CopyOnWriteArrayList默认是线程安全的
public class TestJUC {
public static void main(String[] args) {
CopyOnWriteArrayList<String> copyOnWriteArrayList=new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
copyOnWriteArrayList.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(copyOnWriteArrayList.size());
}
}
死锁

死锁的情况:
package com.mingmao.multithreading.synchronizationmethod;
//死锁:多个线程互相抱着对方需要的资源,相互僵持
public class TestDeadLock {
public static void main(String[] args) {
MakeUp makeUp=new MakeUp(0,"小红");
MakeUp makeUp1=new MakeUp(1,"小丽");
makeUp.start();
makeUp1.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class MakeUp extends Thread {
//需要的资源只有一份,用static
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
private int choice;
private String name;
public MakeUp(int choice, String name) {
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
makeUp();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
//互相持有对方的锁,就是持有对方的资源
private void makeUp() throws InterruptedException {
if (choice == 0) {
synchronized (lipstick) {
System.out.println(this.name + "获得口红");
Thread.sleep(1000);
synchronized (mirror) {
System.out.println(this.name + "获得镜子");
}
}
} else {
synchronized (mirror) {
System.out.println(this.name + "获得镜子");
Thread.sleep(2000);
synchronized (lipstick) {
System.out.println(this.name + "获得口红");
}
}
}
}
}
修改后:
package com.mingmao.multithreading.synchronizationmethod;
//死锁:多个线程互相抱着对方需要的资源,相互僵持
public class TestDeadLock {
public static void main(String[] args) {
MakeUp makeUp=new MakeUp(0,"小红");
MakeUp makeUp1=new MakeUp(1,"小丽");
makeUp.start();
makeUp1.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class MakeUp extends Thread {
//需要的资源只有一份,用static
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
private int choice;
private String name;
public MakeUp(int choice, String name) {
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
makeUp();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
//互相持有对方的锁,就是持有对方的资源
private void makeUp() throws InterruptedException {
if (choice == 0) {
synchronized (lipstick) {
System.out.println(this.name + "获得口红");
Thread.sleep(1000);
}
synchronized (mirror) {
System.out.println(this.name + "获得镜子");
}
} else {
synchronized (mirror) {
System.out.println(this.name + "获得镜子");
Thread.sleep(2000);
}
synchronized (lipstick) {
System.out.println(this.name + "获得口红");
}
}
}
}

Lock锁


package com.mingmao.multithreading.lock;
import java.util.concurrent.locks.ReentrantLock;
//测试Lock锁
public class TestLock {
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 ticketNums=10;
//定义Lock锁
private final ReentrantLock reentrantLock=new ReentrantLock();
@Override
public void run() {
buyTicket();
}
public void buyTicket(){
while (true){
//加锁
try {
reentrantLock.lock();
if(ticketNums<=0){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
} catch (Exception e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
}
线程通信





管程法
package com.mingmao.multithreading.threadcommunication;
//测试生产者消费者模型--利用缓冲区解决:管程法
public class PipeProgramMethod {
public static void main(String[] args) {
Syncontainer syncontainer=new Syncontainer();
new Producer(syncontainer).start();
new Consumer(syncontainer).start();
}
}
//生产者
class Producer extends Thread{
Syncontainer syncontainer;
public Producer(Syncontainer syncontainer){
this.syncontainer=syncontainer;
}
//生产
@Override
public void run() {
for (int i = 0; i <100; i++) {
syncontainer.push(new Product(i));
System.out.println("生产出了第"+(i+1)+"个产品");
}
}
}
//消费者
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+1)+"个产品");
}
}
}
//产品
class Product{
int id;//产品编号
public Product(int id) {
this.id = id;
}
}
//缓冲区
class Syncontainer {
private Product[] products = new Product[10];//容器大小
private int num = 0;//产品数量
//生产者放入产品
public synchronized void push(Product product) {
//容器满了,等待消费者消费
if (num == products.length) {
//通知消费者消费,生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
//否则放入产品
products[num] = product;
num++;
//通知消费者消费
this.notifyAll();
}
//消费者消费产品
public synchronized Product pop() {
//判断是否有产品,没有就等待
if (num == 0) {
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
//否则,取走产品
num--;
Product product = products[num];
//吃完了,通知生产者生产
this.notifyAll();
return product;
}
}
信号灯法
package com.mingmao.multithreading.threadcommunication;
//测试生产者消费者问题:信号灯法,标志位解决
public class SignalLampMethod {
public static void main(String[] args) {
TV tv=new TV();
new Performer(tv).start();
new Audience(tv).start();
}
}
//生产者--演员
class Performer extends Thread{
TV tv=new TV();
public Performer(TV tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
tv.play("第"+(i+1)+"个节目");
}
}
}
//消费者--观众
class Audience extends Thread{
TV tv=new TV();
public Audience(TV tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
tv.watch("第"+(i+1)+"个节目");
}
}
}
//产品--节目
class TV{
//演员表演,观众等待 true
//观众观看,演员等待false
String program;//节目
private boolean flag=true;//标志
//表演
public synchronized void play(String program){
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
System.out.println("演员表演了"+program);
//通知观众观看
this.notifyAll();
this.program=program;
flag=!this.flag;
}
//观看
public synchronized void watch(String program){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
System.out.println("观众观看了"+program);
//通知演员表演
this.notifyAll();
flag=!this.flag;
}
}
线程池

package com.mingmao.multithreading.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestPool {
public static void main(String[] args) {
/* 常规方法
MyThread myThread=new MyThread();
new Thread(myThread).start();
*/
//创建服务,线程池
ExecutorService executorService= Executors.newFixedThreadPool(10);//参数为线程池大小
//执行
executorService.execute(new MyThread());
executorService.execute(new MyThread());
executorService.execute(new MyThread());
executorService.execute(new MyThread());
//关闭连接
executorService.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}
}

浙公网安备 33010602011771号