狂神说java多线程
程序 进程 线程
Process 进程
Thread 线程
多线程核心概念
java程序在启动时就有main线程和gc垃圾回收线程
线程的创建
继承Thread类
//创建一个线程 继承Thread 重写run()方法 调用start 开启线程
//线程开启不一定立即执行 有cpu调度
public class TestThread_01 extends Thread{
@Override
public void run() {
// run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("学习多线程"+i);
}
}
public static void main(String[] args) {
// 创建一个线程对象
TestThread_01 thread_01 = new TestThread_01();
// 调用start 方法
thread_01.start();
for (int i = 0; i < 10; i++) {
System.out.println("这是主线程"+i);
}
}
}
创建一个线程 继承Thread 重写run()方法 调用start 开启线程
线程开启不一定立即执行 由cpu调度
实现Runnable接口
//创建线程 实现Runnable 接口 重写run方法
public class TestRunnable_01 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("多线程"+i);
}
}
public static void main(String[] args) {
// 创建runnable接口的实现类对象
TestRunnable_01 testrunnbale_01 = new TestRunnable_01();
// 创建线程对象来开启我们的线程代理
Thread thread_01 = new Thread(testrunnbale_01);
// 开启线程
thread_01.start();
for (int i = 0; i < 10; i++) {
System.out.println("主线程"+i);
}
}
}
查看Thread类源码发现也实现了Runbale类
public
class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
因为java单继承的局限性,所以Thread继承比较局限所以推荐使用Runnable接口实现
java龟兔赛跑Runnable 接口
package 多线程使用;
//龟兔赛跑
public class Race implements Runnable{
// 胜利者
static String winner;
@Override
public void run() {
for (int i = 1; i < 105; i++) {
if(Thread.currentThread().getName().equals("兔子")&&i%30==0){
try {
//兔子休息一下
Thread.sleep(1);
System.out.println(Thread.currentThread().getName()+"休息了1毫秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 判断比赛是否结束
boolean flag = gameover(i);
if (flag) break;
System.out.println(Thread.currentThread().getName()+"现在是第:"+i+"步");
}
}
private boolean gameover(int step){
// 判断是否有胜利者
if(winner !=null){
// 已经存在胜利者
return true;
}else {
if (step == 100){
winner = Thread.currentThread().getName();
System.out.println("winner--"+winner+"已经跑了:"+step);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race r_01 = new Race();
Race r_02 = new Race();
new Thread(r_01,"兔子").start();
new Thread(r_02,"乌龟").start();
}
}
实现Callable接口
package 多线程使用;
import java.util.concurrent.*;
/*
使用callable接口实现线程
callable的好处
1可以定义返回值
2可以抛出异常
*/
public class TestCallable implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println("主线程在执行"+i);
}
return true;
}
public static void main(String[] args) {
TestCallable call_01 = new TestCallable();
TestCallable call_02 = new TestCallable();
// 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(2);
// 提交执行
Future<Boolean> future_01 = ser.submit(call_01);
Future<Boolean> future_02 = ser.submit(call_02);
// 获取结果
try {
Boolean res01 = future_01.get();
Boolean res02 = future_02.get();
System.out.println(res01);
System.out.println(res02);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 关闭服务
ser.shutdown();
}
}
静态代理模式
静态代理模式总结
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色
代理对象可以做很多真实对象做不了的事情
真实对象专注做自己的事情
package 静态代理;
/*
静态代理模式总结
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色
代理对象可以做很多真实对象做不了的事情
真实对象专注做自己的事情
*/
public class StaticProxy {
public static void main(String[] args) {
// 你要结婚
Me m = new Me();
/*
Thread代理真实对象runnable接口 然后调用start方法
*/
new Thread(()-> System.out.println("我爱你")).start();
new WeddingCompany(new Me()).HappyMarry();
//
WeddingCompany wedding = new WeddingCompany(m);
wedding.HappyMarry();
}
}
//定义接口
interface Marry{
void HappyMarry();
}
class Me 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() {
bebore();
// 真实对象
this.target.HappyMarry();
after();
}
private void after() {
System.out.println("结婚之后收尾款");
}
private void bebore() {
System.out.println("结婚之前布置现场");
}
}
线程的五大状态
使用标志位停止线程,不推荐使用stop() destroy()方法
package 多线程使用;
/*
建议线程正常停止_->利用次数,不建议死循环
建议使用标志位->设置一个标志位
不要使用stop或者destroy过时或者jdk不建议的方法
*/
public class Teststop_thread implements Runnable{
// 设置一个标志位
private boolean flag=true;
@Override
public void run() {
while (flag){
System.out.println("next run...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 设置一个公开方法停止线程,转换标志位
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
Teststop_thread t_01 = new Teststop_thread();
Thread thread_01 = new Thread(t_01);
thread_01.start();
for (int i = 0; i < 200; i++) {
if(i==100){
// 调用停止方法
t_01.stop();
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程休眠
模拟网络延迟 发现问题的发生性
package 多线程使用;
//模拟网络延迟 发现问题的发生性
public class Testsleep implements Runnable{
private int number=10;
@Override
public void run() {
while (true){
if(number<=0)break;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+number--+"张票");
}
}
public static void main(String[] args) {
Testsleep ts = new Testsleep();
Thread th_01 = new Thread(ts,"小明");
Thread th_02 = new Thread(ts,"小红");
Thread th_03 = new Thread(ts,"黄牛");
th_01.start();
th_02.start();
th_03.start();
}
}
模拟倒计时
package 多线程使用;
public class Testsleep_02 implements Runnable{
private int number =10;
@Override
public void run() {
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tenDown() throws InterruptedException{
while (true){
Thread.sleep(100);
System.out.println(number--);
if(number<=0) break;
}
}
public static void main(String[] args) {
Testsleep_02 t1 = new Testsleep_02();
Thread th = new Thread(t1,"线程1");
th.start();
}
}
join方法线程插队
在使用join方法前已经启动的线程是并行的 当前线程使用join方法后会阻塞其他线程 优先执行当前线程
package 多线程使用;
//测试join方法
public class Testjoin implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("线程join测试"+i);
}
}
public static void main(String[] args) {
// 启动我们的线程
Testjoin join_01=new Testjoin();
Thread th = new Thread(join_01);
th.start();
//主线程
for (int i = 0; i < 1000; i++) {
System.out.println("主线程正在执行"+i);
if(i==200) {
try {
// 插队
th.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
线程状态
-
线程状态。线程可以处于以下状态之一:
- NEW
尚未启动的线程处于此状态。 - RUNNABLE
在Java虚拟机中执行的线程处于此状态。 - BLOCKED
被阻塞等待监视器锁定的线程处于此状态。 - WAITING
正在等待另一个线程执行特定动作的线程处于此状态。 - TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。 - TERMINATED
已退出的线程处于此状态。
一个线程可以在给定时间点处于一个状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。
线程进入死亡状态不能再次启动
- NEW
查看线程状态
package 多线程使用;
public class TestSate implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("子线程"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TestSate test=new TestSate();
Thread th_01=new Thread(test);
Thread.State state = th_01.getState();
// 观察状态启动前的状态
System.out.println(state);
th_01.start();
// 观察启动后的状态
state = th_01.getState();
System.out.println(state);
while (state !=Thread.State.TERMINATED){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 更新线程状态
state = th_01.getState();
System.out.println(state);
}
// 死亡之后的线程不能再启动
th_01.start();
}
}
线程优先级
优先级高的不一定会先执行
package 多线程使用;
public class Testpriority {
public static void main(String[] args) {
// 主线程默认优先级
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
Mypriority mypriority = new Mypriority();
Thread th_01 = new Thread(mypriority,"二号线程");
Thread th_02 = new Thread(mypriority,"三号线程");
Thread th_03 = new Thread(mypriority,"一号");
Thread th_04 = new Thread(mypriority,"四号");
Thread th_05 = new Thread(mypriority,"五号");
// 先设置优先级
th_01.start();
th_02.setPriority(1);
th_02.start();
th_03.setPriority(4);
th_03.start();
th_04.setPriority(Thread.MAX_PRIORITY);
th_04.start();
th_05.setPriority(7);
th_05.start();
}
}
class Mypriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
守护线程
- 一个线程创建时默认为用户线程
- 通过setDaemon(true)可以将一个线程设置为守护线程
- java虚拟机会确保用户线程执行完毕
- java虚拟机不会等待守护线程执行完毕
- 当用户线程全部结束后,守护线程将会终止
- 比如后台记录操作日志 监控内存 gc垃圾回收 都是守护线程
package 多线程使用;
//测试守护线程
public class Testdaemon {
public static void main(String[] args) {
God g = new God();
You y = new You();
Thread th_01 = new Thread(g);
Thread th_02 = new Thread(y);
// 设置为守护线程
th_01.setDaemon(true);
// 守护线程启动了
th_01.start();
th_02.start();
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("真好");
}
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("God保佑你");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心得活着");
}
System.out.println("goodbye ! word===");
}
}
并发
同一个线程对象被多个线程同时操作
队列+锁才能保证线程同步的安全性
线程不安全例子
例子1
package 多线程使用.线程安全;
//不安全的取钱
public class UnsafeBank {
public static void main(String[] args) {
// 账户
Accout accout = new Accout(100, "中国银行");
Drawing Me = new Drawing(accout,50,"我自己");
Drawing girlfriend = new Drawing(accout,100,"女朋友");
Me.start();
girlfriend.start();
}
}
//账户
class Accout{
int money;
String name;
public Accout(int money, String name) {
this.money = money;
this.name = name;
}
}
class Drawing extends Thread{
// 账户
Accout accout;
// 取了多少钱
int drawingMoney;
// 现在手里还有多少钱
int nowMoney;
public Drawing(Accout accout,int drawingMoney,String name){
this.accout=accout;
this.drawingMoney=drawingMoney;
super.setName(name);
}
//取钱
@Override
public void run() {
// 判断有没有钱
if(accout.money - drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够取,取不了");
return;
}
// sleep放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 卡内余额 = 余额-你取的钱
accout.money = accout.money-drawingMoney;
nowMoney=nowMoney+drawingMoney;
System.out.println(accout.name+"余额为:"+accout.money);
// Thread.currentThread().getName() == this.getName()
System.out.println(this.getName()+"手里的钱:"+nowMoney);
}
}
例子2
package 多线程使用.线程安全;
public class UnsafebuyTicket {
public static void main(String[] args) {
BuyTicket ticket = new BuyTicket();
Thread th_01 = new Thread(ticket, "小明");
Thread th_02 = new Thread(ticket, "黄牛");
Thread th_03 = new Thread(ticket, "苦逼的我");
th_01.start();
th_02.start();
th_03.start();
}
}
class BuyTicket implements Runnable{
// 票
private int ticketNums =10;
private boolean flag=false;
@Override
public void run() {
// 买票
while (true){
buy();
if(flag) break;
}
}
private void buy(){
// 判断是否有票
if(ticketNums<=0){
flag=true;
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
例子3
package 多线程使用.线程安全;
import java.util.ArrayList;
import java.util.List;
public class Unsafelist {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
Thread th = new Thread(()->{
list.add(Thread.currentThread().getName());
});
th.start();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
synchronize线程锁
每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
synchronize同步方法
在方法上加修饰词synchronize锁的是当前对象
同步方法的弊端性能低 因为只需要修改的变量资源才需要上锁
synchronize同步代码块
同步代码块可以锁任意指定对象
synchronized代码块同步锁的例子模拟银行操作
package 多线程使用.线程安全;
//不安全的取钱
public class UnsafeBank {
public static void main(String[] args) {
// 账户
Accout accout = new Accout(1000, "中国银行");
Drawing Me = new Drawing(accout,50,"我自己");
Drawing girlfriend = new Drawing(accout,100,"女朋友");
Me.start();
girlfriend.start();
}
}
//账户
class Accout{
int money;
String name;
public Accout(int money, String name) {
this.money = money;
this.name = name;
}
}
class Drawing extends Thread{
// 账户
Accout accout;
// 取了多少钱
int drawingMoney;
// 现在手里还有多少钱
int nowMoney;
public Drawing(Accout accout,int drawingMoney,String name){
this.accout=accout;
this.drawingMoney=drawingMoney;
super.setName(name);
}
//取钱
// synchronized 修饰方法默认锁的是this
// synchronized 代码块锁任意指定对象
@Override
public void run() {
// synchronized代码块锁指定对象
// 锁的对象就是变化的量
synchronized (accout){
// 判断有没有钱
if(accout.money - drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够取,取不了");
return;
}
// sleep放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 卡内余额 = 余额-你取的钱
accout.money = accout.money-drawingMoney;
nowMoney=nowMoney+drawingMoney;
System.out.println(accout.name+"余额为:"+accout.money);
// Thread.currentThread().getName() == this.getName()
System.out.println(this.getName()+"手里的钱:"+nowMoney);
}
}
}
synchronized同步方法的例子模拟买票
package 多线程使用.线程安全;
public class UnsafebuyTicket {
public static void main(String[] args) {
BuyTicket ticket = new BuyTicket();
Thread th_01 = new Thread(ticket, "小明");
Thread th_02 = new Thread(ticket, "黄牛");
Thread th_03 = new Thread(ticket, "苦逼的我");
th_01.start();
th_02.start();
th_03.start();
}
}
class BuyTicket implements Runnable{
// 票
private int ticketNums =10;
private boolean flag=false;
@Override
public void run() {
// 买票
while (true){
buy();
if(flag) break;
}
}
// synchronized 同步方法
private synchronized void buy(){
// 判断是否有票
if(ticketNums<=0){
flag=true;
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
**synchronized 代码块同步锁的例子Arraylist **
ArrayList是线程不安全的,因为多线程在操作list的空间会同时写到同一块内存位置,然后会覆盖掉之前的内容
package 多线程使用.线程安全;
import java.util.ArrayList;
import java.util.List;
public class Unsafelist {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
synchronized(list) {
for (int i = 0; i < 100; i++) {
Thread th = new Thread(() -> {
list.add(Thread.currentThread().getName());
});
th.start();
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
JUC并发下的线程安全的集合CopyOnWriteArrayList
package 多线程使用.线程安全;
import java.util.concurrent.CopyOnWriteArrayList;
//测试juc安全类型的集合
public class TestJuc {
public static void main(String[] args) {
CopyOnWriteArrayList list = new CopyOnWriteArrayList<String>();
for (int i = 0; i < 100; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
死锁
死锁 多个线程互相抱着对方的需要的资源 ,然后形成互相僵持
package 多线程使用.线程安全;
//死锁 多个线程互相抱着对方的需要的资源 ,然后形成互相僵持
public class DeadLock {
public static void main(String[] args) {
Makeup makeup_01 = new Makeup(0, "大美女");
Makeup makeup_02 = new Makeup(1,"小姐姐");
makeup_01.start();
makeup_02.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
// 需要的资源只有一份,用static来保证
static Lipstick li =new Lipstick();
static Mirror mi = new Mirror();
//
int choice;
String girlName;
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 (li){
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);
synchronized (mi){
// 一秒钟后获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
}
}
}else {
synchronized (mi){
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);
synchronized (li){
// 一秒钟后获得镜子的锁
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
}
释放掉对方需要的对象
package 多线程使用.线程安全;
//死锁 多个线程互相抱着对方的需要的资源 ,然后形成互相僵持
public class DeadLock {
public static void main(String[] args) {
Makeup makeup_01 = new Makeup(0, "大美女");
Makeup makeup_02 = new Makeup(1,"小姐姐");
makeup_01.start();
makeup_02.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
// 需要的资源只有一份,用static来保证
static Lipstick li =new Lipstick();
static Mirror mi = new Mirror();
//
int choice;
String girlName;
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 (li){
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);
}
synchronized (mi){
// 一秒钟后获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
}
}else {
synchronized (mi){
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);
}
synchronized (li){
// 一秒钟后获得镜子的锁
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
Lock锁
在juc并发包下
// 定义lock可重入锁
private ReentrantLock re = new ReentrantLock();
synchronized与Lock的对比
线程通信
模拟生产者和消费者
生产者消费者模型->利用缓冲区解决:管程法
package 多线程使用.线程协作;
//测试:生产者消费者模型->利用缓冲区解决:管程法
//生产者 消费者 产品 缓冲区
public class TestPc {
public static void main(String[] args) {
SynContainer sy = new SynContainer();
new Productor(sy).start();
new Consumer(sy).start();
}
}
//生产者
class Productor extends Thread{
private SynContainer sy;
Productor (SynContainer sy){
this.sy=sy;
}
@Override
public void run() {
for (int i = 1; i < 100; i++) {
this.sy.push(new Chicken(i));
System.out.println("正在生产第:"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
private SynContainer sy;
Consumer (SynContainer sy){
this.sy=sy;
}
@Override
public void run() {
for (int i = 1; i < 100; i++) {
System.out.println("正在消费第:"+this.sy.pop().id+"只鸡");
}
}
}
//产品
class Chicken{
int id;
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer{
Chicken[] ch=new Chicken[10];
int cont=0;
public synchronized void push(Chicken chicken){
if(cont==ch.length){
// 生产满了等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 生产产品
ch[cont]=chicken;
cont++;
// 通知消费者消费
this.notifyAll();
}
public synchronized Chicken pop(){
// 没有产品了等待生产者
if(cont==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费通知生产者生产
cont--;
Chicken chicken = ch[cont];
this.notifyAll();
return chicken;
}
}
信号灯发
package 多线程使用.线程协作;
public class Test_pc2 {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
class Player extends Thread{
TV t;
Player (TV t){
this.t=t;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%3==0){
t.paly("演员表示节目:"+i);
}else t.paly("正在播放广告"+i);
}
}
}
class Watcher extends Thread{
TV t;
Watcher (TV t){
this.t=t;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
t.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);
flag=!flag;
// 通知观众线程观看
this.voice=voice;
this.notifyAll();
}
public synchronized void watch(){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观众观看:"+this.voice);
flag=!flag;
// 通知演员生产
this.notifyAll();
}
}
线程池的使用
package 多线程使用.线程协作;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//测试线程池
public class Testpool {
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类
- 实现Runnable接口
- 实现Callable接口
表演:"+voice);
flag=!flag;
// 通知观众线程观看
this.voice=voice;
this.notifyAll();
}
public synchronized void watch(){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(“观众观看:”+this.voice);
flag=!flag;
// 通知演员生产
this.notifyAll();
}
}
#### 线程池的使用
[外链图片转存中...(img-xpgsbX0B-1625890820023)]
[外链图片转存中...(img-qGCsJksq-1625890820024)]
```java
package 多线程使用.线程协作;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//测试线程池
public class Testpool {
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类
- 实现Runnable接口
- 实现Callable接口