- 静态代理
- 各种内部类
- yield join后是继续执行 不是重新开始
- sleep的性质 sleep不会释放锁? wait会
- 每个线程都有自己的工作内存 内存都是各自的 互不影响 是拷贝过去的?
- 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
- synchronized方法 释放锁后在哪里重新分配
线程创建
package com.thread.thread_create;
//线程创建方式一:继承Thread类,重写run()方法,调用start开启线程
//总结:注意,线程开启不一定立即执行,由CPU调度执行
public class ThreadCreateDemo01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("子线程执行输出"+i);
}
}
public static void main(String[] args) {
Thread tcd = new ThreadCreateDemo01();
tcd.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程执行输出"+i);
}
}
}
/*public class ThreadCreateDemo01 {
public static void main(String[] args) {
Thread tcd = new MyThread();
tcd.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程执行输出"+i);
}
}
}
class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程执行输出"+i);
}
}
}*/
package com.thread.thread_create;
//案例 网图下载
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class ThreadCreateTest02 extends Thread{
private String url;
private String pathname;
public ThreadCreateTest02(String url,String pathname){
this.url = url;
this.pathname = pathname;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,pathname);
System.out.println("拷贝完成:"+pathname);
}
public static void main(String[] args) {
Thread t1 = new ThreadCreateTest02("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"basic grammar\\src\\com\\thread\\t1.png");
Thread t2 = new ThreadCreateTest02("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"D:\\JavaProjects\\JavaSE\\basic grammar\\src\\com\\thread\\t2.png");
Thread t3 = new ThreadCreateTest02("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"basic grammar\\src\\com\\thread\\t3.png");
t1.start();
t2.start();
t3.start();//每次先后顺序不同
}
}
class WebDownloader{
public void downloader(String url,String pathname) {
try {
FileUtils.copyURLToFile(new URL(url),new File(pathname));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.thread.thread_create;
//创建线程方式二 实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类.调用start方法。
public class ThreadCreateDemo03 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("子线程执行输出"+i);
}
}
public static void main(String[] args) {
ThreadCreateDemo03 tcd = new ThreadCreateDemo03();
new Thread(tcd).start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程执行输出"+i);
}
}
}
/*public class ThreadCreateDemo03 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
new Thread(mr).start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程执行输出"+i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("子线程执行输出"+i);
}
}
}*/
package com.thread.thread_create;
//并发问题
//买火车票案例
//多个线程操作同一个资源的情况下,线程不安全,数据紊乱.
public class ThreadConcurrencyTest04 {
public static void main(String[] args) {
BuyTickets bt = new BuyTickets();
new Thread(bt,"小明").start();
new Thread(bt,"老师").start();
new Thread(bt,"黄牛").start();
}
}
class BuyTickets implements Runnable{
private int ticketNums = 10;
@Override
public void run() {
while(true){
if (ticketNums <= 0){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + "抢到了第" + ticketNums-- + "张票");
}
}
}
package com.thread.thread_create;
//龟兔赛跑案例
public class Race05 {
public static void main(String[] args) {
Race r = new Race();
new Thread(r,"rabbit").start();
new Thread(r,"tortoise").start();
}
}
class Race implements Runnable{
private String winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (winner != null){
break;
}
if (Thread.currentThread().getName() == "rabbit"){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
if (i >= 100 && winner == null){
winner = Thread.currentThread().getName();
System.out.println(winner + "赢了!");
}
}
}
}
package com.thread.thread_create;
/*线程创建方式三:实现callable接口
callable的好处
1.可以定义返回值
2.可以抛出异常 */
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
public class CallableDemo06 implements Callable<Boolean> {
private String url;
private String pathname;
public CallableDemo06(String url, String pathname){
this.url = url;
this.pathname = pathname;
}
@Override
public Boolean call() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,pathname);
System.out.println("拷贝完成:"+pathname);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableDemo06 cd1 = new CallableDemo06("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"basic grammar\\src\\com\\thread\\t1.png");
CallableDemo06 cd2 = new CallableDemo06("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"basic grammar\\src\\com\\thread\\t2.png");
CallableDemo06 cd3 = new CallableDemo06("/i/l/?n=22&i=blog/2836892/202211/2836892-20221118143133840-745717499.png"
,"basic grammar\\src\\com\\thread\\t3.png");
///创建执行服务:
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> r1 = ser.submit(cd1);
Future<Boolean> r2 = ser.submit(cd2);
Future<Boolean> r3 = ser.submit(cd3);
//获取结果
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get();
System.out.println(rs1);
System.out.println(rs2);
//关闭服务
ser.shutdownNow();
}
}
class WebDownloader2{
public void downloader(String url,String pathname) {
try {
FileUtils.copyURLToFile(new URL(url),new File(pathname));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.thread.thread_create;
//线程创建小结
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Summary07 {
public static void main(String[] args) {
new MyThread1().start();
new Thread(new MyThread2()).start();
// Callable<Integer> callable = new MyThread3();
// FutureTask<Integer> futureTask = new FutureTask<>(callable);
FutureTask<Integer> futureTask = new FutureTask<>(new MyThread3());
new Thread(futureTask).start();
try {
Integer integer = futureTask.get();
System.out.println(integer);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
class MyThread1 extends Thread{
@Override
public void run() {
System.out.println("MyThread-->1");
}
}
class MyThread2 implements Runnable{
@Override
public void run(){
System.out.println("MyThread-->2");
}
}
class MyThread3 implements Callable<Integer>{
@Override
public Integer call(){
System.out.println("MyThread-->3");
return 100;
}
}
静态代理
package com.thread.static_proxy;
//静态代理对比
public class StaticProxyTest01 {
public static void main(String[] args) {
/*new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程执行输出");
}
}).start();*/
new Thread(() -> System.out.println("子线程执行输出") ).start();
new WeddingCompany(new person()).happyMarry();
}
}
interface Marry{
void happyMarry();
}
class person implements Marry{
@Override
public void happyMarry() {
System.out.println("XXX今天结婚了");
}
}
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany() {
}
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.thread.lambda_supplement;
//lambda 补充
public class LambdaSupplement01 {
static class Like2 implements Like{
@Override
public void likeExpress() {
System.out.println("i like2");
}
}
class Like3 implements Like{
@Override
public void likeExpress() {
System.out.println("i like3");
}
}
public static void main(String[] args) {
Like like = new Like1();
like.likeExpress();
like = new Like2();
like.likeExpress();
LambdaSupplement01 ls = new LambdaSupplement01();
like = ls.new Like3();
like.likeExpress();
class Like4 implements Like{
@Override
public void likeExpress() {
System.out.println("i like4");
}
}
like = new Like4();
like.likeExpress();
like = new Like(){
@Override
public void likeExpress() {
System.out.println("i like5");
}
};
like.likeExpress();
like = () -> System.out.println("i like6 lambda");
like.likeExpress();
}
}
interface Like{
void likeExpress();
}
class Like1 implements Like{
@Override
public void likeExpress() {
System.out.println("i like1");
}
}
线程状态
package com.thread.thread_state;
/*测试stop
1.建议线程正常停止--->利用次数,不建议死循环。
2.建议使用标志位--->设置一个标志位
3.不要使用stop或者destroy等过时或者JDK不建议使用的方法
*/
public class ThreadStopTest01 implements Runnable{
//设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while(flag){
System.out.println("run...Thread"+ i++);
}
}
//设置一个公开的方法停止线程,转换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
ThreadStopTest01 tst = new ThreadStopTest01();
new Thread(tst).start();
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
if (i == 90){
tst.stop();
System.out.println("线程该停止了");
}
}
}
}
package com.thread.thread_state;
//模拟网络延时 放大问题的发生性。
public class ThreadSleepTest02 {
public static void main(String[] args) {
BuyTickets bt = new BuyTickets();
new Thread(bt,"小明").start();
new Thread(bt,"老师").start();
new Thread(bt,"黄牛").start();
}
}
class BuyTickets implements Runnable {
private int ticketNums = 10;
@Override
public void run() {
while (true) {
if (ticketNums <= 0) {
break;
}
//模拟网络延时
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + "抢到了第" + ticketNums-- + "张票");
}
}
}
package com.thread.thread_state;
//sleep两个例子
import java.text.SimpleDateFormat;
import java.util.Date;
public class ThreadSleepTest03 {
public static void main(String[] args) {
//打印系统当前时间
Date date = new Date(System.currentTimeMillis());
while(true){
System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
date = new Date(System.currentTimeMillis());
}
// tenDown();
}
//模拟倒计时
public static void tenDown(){
int num = 10;
while(true){
if (num == 0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(num--);
}
}
}
package com.thread.thread_state;
//程序礼让
public class ThreadYieldDemo04 {
public static void main(String[] args) {
Runnable my = new MyYield();
new Thread(my,"a").start();
new Thread(my,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "程序开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "程序结束执行");
}
}
package com.thread.thread_state;
//线程强制执行 join
//Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞
public class ThreadJoinDemo05 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 80; i++) {
System.out.println("此线程先完成执行" + i);
}
}
public static void main(String[] args) throws InterruptedException {
Runnable tjd = new ThreadJoinDemo05();
Thread thread = new Thread(tjd);
thread.start();
for (int i = 0; i < 50; i++) {
if (i == 20){
thread.join();
}
System.out.println("主线程执行"+i);
}
}
}
package com.thread.thread_state;
//线程状态观测
public class ThreadStateDemo06 {
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) {
throw new RuntimeException(e);
}
}
System.out.println("-----------");
});
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);
}
}
}
package com.thread.thread_state;
//线程优先级
//优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调用了,这都是看CPU的调度
public class ThreadPriorityDemo07 {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + "-->"
+ Thread.currentThread().getPriority());
Runnable mp = new MyPriority();
Thread t1 = new Thread(mp);
Thread t2 = new Thread(mp);
Thread t3 = new Thread(mp);
Thread t4 = new Thread(mp);
Thread t5 = new Thread(mp);
Thread t6 = new Thread(mp);
t1.start();
t2.setPriority(Thread.MIN_PRIORITY);
t2.start();
t3.setPriority(Thread.MAX_PRIORITY);
t3.start();
t4.setPriority(4);
t4.start();
t5.setPriority(6);
t5.start();
t6.setPriority(8);
t6.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "-->"
+ Thread.currentThread().getPriority());
}
}
package com.thread.thread_state;
//守护线程
public class DaemonDemo08 {
public static void main(String[] args) {
Runnable god = new God();
Runnable person = new Person();
Thread thread = new Thread(god);
thread.setDaemon(true);
thread.start();
new Thread(person).start();
}
}
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("守护");
}
}
}
class Person implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("开心地活着");
}
System.out.println("=====goodbye,world======");
}
}
线程同步
package com.thread.thread_synchronized;
//案例 ---> synchronized 解决
public class UnsafeTicketBuyingDemo01 {
public static void main(String[] args) {
Runnable bt = new BuyTickets();
new Thread(bt,"小明").start();
new Thread(bt,"老师").start();
new Thread(bt,"黄牛").start();
}
}
class BuyTickets implements Runnable{
private int ticketNums = 10;
private boolean flag = true;
@Override
public void run() {
while (flag){
//放大问题的发生性 对synchronized修饰后的情况进行放大
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
buy();
}
}
//全是小明?在上面加了sleep ok了
public synchronized void buy(){
if (ticketNums <= 0){
flag = false;
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + "买到了第" + ticketNums-- + "张票");
}
}
package com.thread.thread_synchronized;
//不安全的取钱案例---> synchronized 解决
public class UnsafeBankDemo02 {
public static void main(String[] args) {
Account account = new Account("结婚基金",100);
Thread wm1 = new WithdrawMoney(account,50,"小明");
Thread wm2 = new WithdrawMoney(account,100,"小红");
wm1.start();
wm2.start();
}
}
class Account{
String name;
int balance;
public Account(){
}
public Account(String name,int balance){
this.name = name;
this.balance = balance;
}
}
class WithdrawMoney extends Thread{
private Account account;
private int withdrawMoney;
private int nowMoney;
public WithdrawMoney(Account account,int withdrawMoney,String name){
super(name);
this.account = account;
this.withdrawMoney = withdrawMoney;
}
@Override
public void run() {
synchronized(account){
if (account.balance - withdrawMoney < 0){
System.out.println(Thread.currentThread().getName() + " 余额不足");
return;
}
//放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
account.balance -= withdrawMoney;
nowMoney += withdrawMoney;
System.out.println(account.name+ "余额为:" + account.balance);
System.out.println(this.getName()+ "手里的钱为:" + nowMoney);
}
}
}
package com.thread.thread_synchronized;
//线程不安全的集合 ArrayList---> synchronized 解决
import java.util.ArrayList;
import java.util.List;
public class UnsafeListDemo03 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {// 2000 or 10000
//无论i是多少 加不加synchronized 都不会覆盖
// new Thread(() -> {
// synchronized (list) {
// list.add(Thread.currentThread().getName());
// }
// }
// ).start();
//数组会被覆盖 无论i是多少
// new Thread( () -> {
//
// //放大问题的发生性 导致覆盖
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
//
// try {
// list.add(Thread.currentThread().getName());
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
//
// }
// ).start();
//在i=100时 ,这样就不会覆盖 主线程阻塞需要20s
new Thread( () -> {
synchronized (list){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
list.add(Thread.currentThread().getName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
).start();
}
//主线程阻塞 等循环结束
try {
Thread.sleep(1000);//在放大了的情况下,i越大,就需要越多的等待时间;不放大就不需要太多
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(list.size());
}
}
package com.thread.thread_synchronized;
//测试JUC安全类型的集合
import java.util.concurrent.CopyOnWriteArrayList;
public class JUCTest04 {
public static void main(String[] args) throws InterruptedException {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 5000; i++) {
new Thread(() -> list.add(Thread.currentThread().getName()) ).start();
}
Thread.sleep(3000);
System.out.println(list.size());
}
}
死锁
package com.thread.deadlock;
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持.
public class DeadlockDemo01 {
public static void main(String[] args) {
Thread m1 = new Makeup(1,"灰姑娘");
Thread m2 = new Makeup(2,"白雪公主");
m1.start();
m2.start();
}
}
class Mirror{}
class Lipstick{}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Mirror mirror = new Mirror();
static Lipstick lipstick = new Lipstick();
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) {
throw new RuntimeException(e);
}
}
public void makeUp() throws InterruptedException {
if (choice == 1){
synchronized(mirror){
System.out.println(this.name+"拿到了镜子");
Thread.sleep(1000);
// synchronized (lipstick){
// System.out.println(this.name+"拿到了口红");
// }
}
synchronized (lipstick){
System.out.println(this.name+"拿到了口红");
}
}else{
synchronized(lipstick){
System.out.println(this.name+"拿到了口红");
Thread.sleep(1000);
// synchronized (mirror){
// System.out.println(this.name+"拿到了镜子");
// }
}
synchronized (mirror){
System.out.println(this.name+"拿到了镜子");
}
}
}
}
Lock锁
package com.thread.lock;
//测试Lock锁
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo01 {
public static void main(String[] args) {
Runnable bt = new BuyTicket();
new Thread(bt).start();
new Thread(bt).start();
new Thread(bt).start();
}
}
class BuyTicket implements Runnable{
private int ticketNums = 10;
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
//不然全是 0 拿票
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try{
lock.lock();
if (ticketNums>0){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}else {
break;
}
}finally {
lock.unlock();
}
}
}
}
线程通信
package com.thread.thread_communication;
//线程通信 生产者与消费者模式 利用缓冲区解决 管程法
/*
通信的方法均是Object类的方法,都只能在同步方法或者同步代码块中使用,
否则会抛出异常IllegalMonitorStateException
*/
public class ProducerAndConsumer01 {
public static void main(String[] args) {
SynContainer sc = new SynContainer();
Thread producer = new Producer(sc);
Thread consumer = new Consumer(sc);
producer.start();
consumer.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 Chicken(i));
System.out.println("生产者生产了第"+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 Chicken{
int id;
public Chicken(int id){
this.id = id;
}
}
class SynContainer{
private Chicken[] chickens = new Chicken[10];
private int count;
public synchronized void push(Chicken chicken){
if (count == chickens.length){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
chickens[count] = chicken;
count++;
this.notifyAll();
}
public synchronized Chicken pop(){
if (count == 0){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
count--;
Chicken chicken = chickens[count];
this.notifyAll();
return chicken;
}
}
package com.thread.thread_communication;
//生产者与消费者模式 信号灯法 标志位解决
public class ProducerAndConsumer02 {
public static void main(String[] args) {
TV tv = new TV();
new Actor(tv).start();
new Audience(tv).start();
}
}
class Actor extends Thread{
TV tv;
public Actor(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i <20 ; i++) {
if (i%2 == 0){
tv.perform("快乐大本营");
}else {
tv.perform("抖音广告");
}
}
}
}
class Audience extends Thread{
TV tv;
public Audience(TV tv){
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
class TV{
private String show;
private boolean flag = true;
public synchronized void perform(String show){
if (!flag){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
this.show = show;
System.out.println("表演了"+show);
this.flag = !this.flag;
this.notifyAll();
}
public synchronized void watch(){
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("观众观看了"+show);
this.flag = !this.flag;
this.notifyAll();
}
}
线程池
package com.thread.thread_pool;
//线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo01 {
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());
}
}
标签:Thread,thread,void,System,new,多线程,public
From: https://www.cnblogs.com/799rijiyuelei/p/16945899.html