本章主要是把多线程这块理清楚
public class ThreadTest extends Thread{
//线程入口点
@Override
public void run(){
//线程体
for (int i = 1; i <= 5; i++) {
System.out.println("已经执行"+i+"秒");
}
}
public static void main(String[] args) {
//创建线程对象
ThreadTest threadTest=new ThreadTest();
threadTest.start();
}
}
//输出结果:
已经执行1秒
已经执行2秒
已经执行3秒
已经执行4秒
已经执行5秒
public class ThreadTest extends Thread{
private String url;
private String name;
public ThreadTest(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run(){
WebDownloader webDownloader=new WebDownloader();
try {
webDownloader.downloader(url,name);
System.out.println("已下载此文件:"+name);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadTest t1=new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p1.png");
ThreadTest t2=new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p2.png");
ThreadTest t3=new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p3.png");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
//文件下载工具类
class WebDownloader{
//远程路径,存储名称
public void downloader(String url,String name) throws IOException {
FileUtils.copyURLToFile(new URL(url),new File(name));
}
}
//输出结果:
已下载此文件:src/img/p3.png
已下载此文件:src/img/p2.png
已下载此文件:src/img/p1.png
public class RunnableTest implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("已经执行"+i+"秒");
}
}
public static void main(String[] args) {
new Thread(new RunnableTest()).start();
}
}
//输出结果:
已经执行1秒
已经执行2秒
已经执行3秒
已经执行4秒
已经执行5秒
public class RunnableTest implements Runnable{
private String url;
private String name;
public RunnableTest(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
try {
webDownloader.downloader(url,name);
System.out.println("已下载此文件:"+name);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Thread(new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p1.png")).start();
new Thread(new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p2.png")).start();
new Thread(new ThreadTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p3.png")).start();
}
}
//输出结果:
已下载此文件:src/img/p3.png
已下载此文件:src/img/p1.png
已下载此文件:src/img/p2.png
public class CallableTest implements Callable<Boolean> {
private String url;
private String name;
public CallableTest(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader=new WebDownloader();
try {
webDownloader.downloader(url,name);
System.out.println("已下载此文件:"+name);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
public static void main(String[] args) {
CallableTest t1=new CallableTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p1.png");
CallableTest t2=new CallableTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p2.png");
CallableTest t3=new CallableTest("https://cdn.jsdelivr.net/gh/jasper807/picgo/cover/javaio.png","src/img/p3.png");
//创建执行服务
ExecutorService ex= Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> result1= (Future<Boolean>) ex.submit(t1);
Future<Boolean> result2= (Future<Boolean>) ex.submit(t2);
Future<Boolean> result3= (Future<Boolean>) ex.submit(t3);
//获取结果
try{
if (result1.get()!=null){
boolean r1= result1.get();
System.out.println("r1="+r1);
}
if (result2.get()!=null){
boolean r2= result2.get();
System.out.println("r2="+r2);
}
if (result3.get()!=null){
boolean r3= result3.get();
System.out.println("r3="+r3);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//关闭服务
ex.shutdownNow();
}
}
//输出结果:
已下载此文件:src/img/p1.png
已下载此文件:src/img/p3.png
r1=true
已下载此文件:src/img/p2.png
r2=true
r3=true
public class Race implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
//模拟兔子休息
if (Thread.currentThread().getName().equals("兔子")&&i%5==0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boolean flag=gameOver(i);
if (flag){
break;
}
System.out.println(Thread.currentThread().getName()+
"--->跑了"+i+"步");
}
}
//判断是否完成比赛
public boolean gameOver(int steps){
//判断是否有胜利者
if (winner!=null){
return true;
}
if (steps>=20){
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();
}
}
//输出结果:
兔子--->跑了1步
兔子--->跑了2步
兔子--->跑了3步
兔子--->跑了4步
乌龟--->跑了1步
乌龟--->跑了2步
乌龟--->跑了3步
乌龟--->跑了4步
乌龟--->跑了5步
乌龟--->跑了6步
乌龟--->跑了7步
乌龟--->跑了8步
乌龟--->跑了9步
乌龟--->跑了10步
乌龟--->跑了11步
乌龟--->跑了12步
乌龟--->跑了13步
乌龟--->跑了14步
乌龟--->跑了15步
乌龟--->跑了16步
乌龟--->跑了17步
乌龟--->跑了18步
乌龟--->跑了19步
winner is 乌龟
public class StaticProxy {
public static void main(String[] args) {
//这个结婚案例相当于模拟线程静态代理,等同于下面
new WeddingCompany(new Man()).getMarry();
new Thread(new Runnable() {
@Override
public void run() {
}
});
}
}
interface Marry{
void getMarry();
}
//真实角色
class Man implements Marry{
@Override
public void getMarry() {
System.out.println("Marry...");
}
}
//代理角色
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void getMarry() {
before();
target.getMarry();
after();
}
private void before(){
System.out.println("Before...");
}
private void after(){
System.out.println("After...");
}
}
//输出结果:
Before...
Marry...
After...
public class LambdaTest {
public static void main(String[] args) {
Tom tom=new Tom();
tom.eatApple(3);
}
}
interface Apple{
void eatApple(int num);
}
class Tom implements Apple{
@Override
public void eatApple(int num) {
System.out.println("Tom 吃了"+ num + "个苹果");
}
}
//输出结果:
Tom吃了3个苹果
public class LambdaTest {
//静态内部类
static class Tom implements Apple{
@Override
public void eatApple(int num) {
System.out.println("Tom吃了"+ num + "个苹果");
}
}
public static void main(String[] args) {
Tom tom=new Tom();
tom.eatApple(3);
}
}
interface Apple{
void eatApple(int num);
}
//输出结果:
Tom吃了3个苹果
public class LambdaTest {
public static void main(String[] args) {
//局部内部类
class Tom implements Apple{
@Override
public void eatApple(int num) {
System.out.println("Tom吃了"+ num + "个苹果");
}
}
Tom tom=new Tom();
tom.eatApple(3);
}
}
interface Apple{
void eatApple(int num);
}
//输出结果:
Tom吃了3个苹果
public class LambdaTest {
public static void main(String[] args) {
Apple tomEatApple=new Apple() {
@Override
public void eatApple(int num) {
System.out.println("Tom吃了"+ num + "个苹果");
}
};
tomEatApple.eatApple(3);
}
}
interface Apple{
void eatApple(int num);
}
//输出结果:
Tom吃了3个苹果
public class LambdaTest {
public static void main(String[] args) {
Apple tomEatApple=(int num)-> {
System.out.println("Tom吃了"+ num + "个苹果");
};
//简化参数类型
tomEatApple=(num)-> {
System.out.println("Tom吃了"+ num + "个苹果");
};
//简化括号
tomEatApple=num-> {
System.out.println("Tom吃了"+ num + "个苹果");
};
//简化花括号
tomEatApple=num-> System.out.println("Tom吃了"+ num + "个苹果");
tomEatApple.eatApple(3);
}
}
interface Apple{
void eatApple(int num);
}
//输出结果:
Tom吃了3个苹果
public class StopTest implements Runnable{
private boolean flag=true;
@Override
public void run() {
while(flag){
System.out.println("run...");
}
}
public void stop(){
this.flag=false;
}
public static void main(String[] args) throws InterruptedException {
StopTest stopTest = new StopTest();
new Thread(stopTest).start();
for (int i = 1; i <= 10; i++) {
System.out.println("main"+i);
if (i==5){
stopTest.stop();
System.out.println("run线程即将停止");
}
}
}
}
//输出结果:
main1
main2
main3
main4
main5
run...
run线程即将停止
main6
main7
main8
main9
main10
public class SleepTest {
//1.模拟延时
//2.打印当前系统时间
public static void getNowTime() throws InterruptedException {
Date startTime=new Date(System.currentTimeMillis());
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime=new Date(System.currentTimeMillis());
}
}
//3.模拟倒计时
public static void timeDown() throws InterruptedException {
int num=5;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
public static void main(String[] args) throws InterruptedException {
getNowTime();
System.out.println("---");
timeDown();
}
}
//输出结果:
11:10:44
11:10:45
11:10:46
11:10:47
11:10:48
---
5
4
3
2
1
//源码
/**
* A hint to the scheduler that the current thread is willing to yield
* its current use of a processor. The scheduler is free to ignore this
* hint.
*
* Yield is a heuristic attempt to improve relative progression
* between threads that would otherwise over-utilise a CPU. Its use
* should be combined with detailed profiling and benchmarking to
* ensure that it actually has the desired effect.
*
*
It is rarely appropriate to use this method. It may be useful
* for debugging or testing purposes, where it may help to reproduce
* bugs due to race conditions. It may also be useful when designing
* concurrency control constructs such as the ones in the
* {@link java.util.concurrent.locks} package.
*/
public static native void yield();
public class YieldTest implements Runnable{
public static void main(String[] args) {
YieldTest yieldTest=new YieldTest();
new Thread(yieldTest,"A").start();
new Thread(yieldTest,"B").start();
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("当前线程为: "+ Thread.currentThread().getName()+ i);
if (i == 3){
Thread.yield();
}
}
}
}
//输出结果:
//情况1 B3之后让出CPU,AB线程同时竞争,A获得CPU,礼让成功
当前线程为: B0
当前线程为: B1
当前线程为: B2
当前线程为: B3
当前线程为: A0
当前线程为: A1
当前线程为: A2
当前线程为: A3
当前线程为: A4
当前线程为: B4
//情况2 A3之后让出CPU,AB线程同时竞争,A获得CPU,没有礼让成
当前线程为: A0
当前线程为: A1
当前线程为: A2
当前线程为: A3
当前线程为: A4
当前线程为: B0
当前线程为: B1
当前线程为: B2
当前线程为: B3
当前线程为: B4
public class JoinTest implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("vip"+i+"...");
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(new JoinTest());
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("main"+i+"...");
if (i==2){
thread.join();
}
}
}
}
//输出结果:
main0...
main1...
main2...
vip0...
vip1...
vip2...
vip3...
vip4...
vip5...
vip6...
vip7...
vip8...
vip9...
main3...
main4...
main5...
main6...
main7...
main8...
main9...
初始(NEW):新创建了一个线程对象,但还没有调用start()方法
运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)
阻塞(BLOCKED):表示线程阻塞于锁
等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)
终止(TERMINATED):表示该线程已经执行完毕
public class StateTest {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行中...");
}
});
Thread.State state=thread.getState();
//NEW
System.out.println(state);
//RUNNABLE
thread.start();
state=thread.getState();
System.out.println(state);
//TERMINATED
while (state!= Thread.State.TERMINATED){
Thread.sleep(100);
state=thread.getState();
System.out.println(state);
}
}
}
//运行结果:
NEW
RUNNABLE
TIMED_WAITING
运行中...
TIMED_WAITING
运行中...
TIMED_WAITING
运行中...
TERMINATED
public class PriorityTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());
}
public static void main(String[] args) {
//主线程优先级
System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());
PriorityTest p=new PriorityTest();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
Thread t4 = new Thread(p);
Thread t5 = new Thread(p);
//先设置优先级再启动
t1.start();
t2.setPriority(Thread.MAX_PRIORITY);
t2.start();
t3.setPriority(Thread.MIN_PRIORITY);
t3.start();
t4.setPriority(7);
t4.start();
t5.setPriority(3);
t5.start();
}
}
//输出结果:
main:5
Thread-1:10
Thread-4:3
Thread-3:7
Thread-2:1
Thread-0:5
public class DaemonTest {
public static void main(String[] args) {
God god=new God();
You you=new You();
Thread thread=new Thread(god);
thread.setDaemon(true);//默认false为用户线程,正常的线程都是用户线程
thread.start();
new Thread(you).start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("守护你...");
}
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (i%3==0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生活中...");
}
System.out.println("生活结束...");
}
}
//输出结果:
生活中...
生活中...
生活中...
守护你...
生活中...
生活中...
生活中...
守护你...
生活中...
生活中...
生活中...
守护你...
生活中...
生活结束...
守护你...
并发:同一个对象被多个线程同时操作
线程同步:处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步。线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用。
由于同一进程的多个线程共享同一块存储空间 , 在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制synchronized,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可。
public synchronized void method(int args) {}
public class BuyTicket{
public static void main(String[] args) {
Ticket ticket=new Ticket();
new Thread(ticket,"用户1").start();
new Thread(ticket,"用户2").start();
new Thread(ticket,"用户3").start();
}
}
class Ticket implements Runnable{
private int ticketNums=10;
boolean flag= true;
@Override
public void run() {
while (flag){
try {
Thread.sleep(1000);
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void buy() {
if (ticketNums<=0){
flag=false;
return;
}
System.out.println(Thread.currentThread().getName()+"买了第"+(10-ticketNums+1)+"张票");
ticketNums--;
}
}
//输出结果:
用户1买了第1张票
用户2买了第2张票
用户3买了第3张票
用户1买了第4张票
用户2买了第5张票
用户3买了第6张票
用户1买了第7张票
用户2买了第8张票
用户3买了第9张票
用户1买了第10张票
synchronized (Obj obj) {}
Obj称之为同步监视器,Obj 可以是任何对象,但是推荐使用共享资源作为同步监视器
同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,就是这个对象本身,或者是class
public class GoBank {
public static void main(String[] args) {
Account account=new Account("Marry Money",100);
Drawing dad=new Drawing(account,50,"dad");
Drawing mom=new Drawing(account,100,"mom");
dad.start();
mom.start();
}
}
//账户
class Account{
private String cardName;//卡名
private int money;//余额
public Account(String cardName, int money) {
this.cardName = cardName;
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public String getCardName() {
return cardName;
}
public void setCardName(String cardName) {
this.cardName = cardName;
}
}
//银行
class Drawing extends Thread{
private Account account;
private int drawingMoney;
private int nowMoney;
private String name;
public Drawing(Account account, int drawingMoney, String name) {
this.account = account;
this.drawingMoney = drawingMoney;
this.name=name;
}
public void run(){
synchronized (account){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断有没有钱
if (account.getMoney()-drawingMoney<0){
System.out.println(name+"钱不够");
return;
}
System.out.println(account.getCardName()+"为"+account.getMoney());
account.setMoney(account.getMoney()-drawingMoney);
nowMoney=nowMoney+drawingMoney;
//Thread.currentThread().getName()=this.getName()
System.out.println(name+"手里的钱"+nowMoney);
System.out.println(account.getCardName()+"余额为"+account.getMoney());
}
}
}
//输出结果:
Marry Money为100
dad手里的钱50
Marry Money余额为50
mom钱不够
//方法1
public class SafeList {
public static void main(String[] args) throws InterruptedException {
List<String> list=new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()-> {
synchronized (list) {
list.add(Thread.currentThread().getName());
}
}).start();
}
Thread.sleep(3000);
System.out.println(list.size());
}
}
//输出结果:
10000
//方法2 使用系统设计的安全类型集合
public class SafeList {
public static void main(String[] args) throws InterruptedException {
CopyOnWriteArrayList<String> list=new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()-> {
list.add(Thread.currentThread().getName());
}).start();
}
Thread.sleep(3000);
System.out.println(list.size());
}
}
//输出结果:
10000
public class DeadLock {
public static void main(String[] args) {
MakeUp girl1=new MakeUp(0,"girl1");
MakeUp girl2=new MakeUp(1,"girl2");
girl1.start();
girl2.start();
}
}
//口红
class LipStick{
}
//镜子
class Mirror{
}
class MakeUp extends Thread{
//static关键字来保证一份
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;
}
public void run(){
//化妆
try {
makeUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeUp() throws InterruptedException {
if (choice==0){
//获得口红的锁
synchronized (lipStick){
System.out.println(girlName+"获得口红的锁");
Thread.sleep(1000);
//获得镜子的锁
synchronized (mirror){
System.out.println(girlName+"获得镜子的锁");
}
}
}else if (choice==1){
//获得镜子的锁
synchronized (mirror){
System.out.println(girlName+"获得镜子的锁");
Thread.sleep(2000);
//获得口红的锁
synchronized (lipStick){
System.out.println(girlName+"获得口红的锁");
}
}
}
}
}
//输出结果:都想拿到对方的锁导致一直卡在这里
girl1获得口红的锁
girl2获得镜子的锁
public class LockTest {
public static void main(String[] args) {
Ticket2 ticket=new Ticket2();
new Thread(ticket,"用户1").start();
new Thread(ticket,"用户2").start();
new Thread(ticket,"用户3").start();
}
}
class Ticket2 implements Runnable{
//定义lock锁
private final ReentrantLock lock=new ReentrantLock();
private int ticketNums=10;
boolean flag= true;
@Override
public void run() {
while (flag){
try {
Thread.sleep(1000);
//加锁
lock.lock();
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//解锁
lock.unlock();
}
}
}
private void buy() {
if (ticketNums<=0){
flag=false;
return;
}
System.out.println(Thread.currentThread().getName()+"买了第"+(10-ticketNums+1)+"张票");
ticketNums--;
}
}
//输出结果:类比同步方法
public class PCTest {
public static void main(String[] args) throws InterruptedException {
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;
}
public void run(){
for (int i = 1; i <= 10; i++) {
try {
container.push(new Chicken(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产了第"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
public void run(){
for (int i = 1; i <= 10; i++) {
try {
System.out.println("消费了第"+container.pop().id+"只鸡");
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//产品
class Chicken{
int id;
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer{
//需要一个容器大小,也就是说这个缓冲区只能放五只鸡,生产者虽然再生产出来鸡,但是之后就会被阻塞
Chicken[] chickens=new Chicken[5];
//容器计数器
int count=0;
//生产者放入产品
public synchronized void push(Chicken chicken) throws InterruptedException {
while (count==chickens.length){
wait();//生产者等待
}
//如果没有满就丢入产品
chickens[count]=chicken;
count++;
//通知消费者消费
notifyAll();
}
//消费者消费产品
public synchronized Chicken pop() throws InterruptedException {
Chicken thisChicken=null;
//判断能否消费
while (count==0){
wait();//消费者等待
}
//如果可以消费
count--;
thisChicken = chickens[count];
//吃完了,通知生产者生产
notifyAll();
return thisChicken;
}
}
//输出结果:
生产了第1只鸡
生产了第2只鸡
生产了第3只鸡
生产了第4只鸡
生产了第5只鸡
消费了第5只鸡
生产了第6只鸡
生产了第7只鸡
消费了第6只鸡
生产了第8只鸡
消费了第7只鸡
消费了第8只鸡
生产了第9只鸡
消费了第9只鸡
生产了第10只鸡
消费了第10只鸡
消费了第4只鸡
消费了第3只鸡
消费了第2只鸡
消费了第1只鸡
public class PCTest2 {
public static void main(String[] args) {
TV tv=new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
//生产者 演员
class Player extends Thread{
TV tv;
public Player(TV tv) {
this.tv = tv;
}
public void run(){
for (int i = 0; i < 5; i++) {
if (i%2==0){
try {
tv.play("节目1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
tv.play("节目2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//消费者 观众
class Watcher extends Thread{
TV tv;
public Watcher(TV tv) {
this.tv = tv;
}
public void run(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(300);
tv.watch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//产品 节目
class TV{
String voice;
boolean flag=true;
//表演
public synchronized void play(String voice) throws InterruptedException {
if (!flag){
wait();
}
System.out.println("演员表演了:"+voice);
//通知观众观看
notifyAll();
this.voice=voice;
this.flag=!this.flag;
}
//观看
public synchronized void watch() throws InterruptedException{
if (flag){
wait();
}
System.out.println("观看了:"+voice);
//通知演员表演
notifyAll();
this.flag=!this.flag;
}
}
//输出结果:
演员表演了:节目1
观看了:节目1
演员表演了:节目2
观看了:节目2
演员表演了:节目1
观看了:节目1
演员表演了:节目2
观看了:节目2
演员表演了:节目1
观看了:节目1
JDK 5.0起提供了线程池相关API:ExecutorService 和 Executors
ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
//测试线程池 Runnable接口为例,Callable上面提到过
public class PoolTest {
public static void main(String[] args) {
//创建服务,创建线程池
ExecutorService ex= Executors.newFixedThreadPool(2);
//执行
ex.execute(new MyThread());
ex.execute(new MyThread());
//关闭连接
ex.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
//输出结果:
pool-1-thread-1 0
pool-1-thread-1 1
pool-1-thread-1 2
pool-1-thread-2 0
pool-1-thread-2 1
pool-1-thread-2 2
Hi, welcome to JasperのBlog!