Java之多线程之自己理解的代码
参考链接:https://www.bilibili.com/video/BV1T7411m7Ta?
匿名内部类构造线程
package xuexi1;
public class Thread1 {
public static void main(String[] args) {
//匿名内部类构造线程,继承Thread
new Thread() {
@Override
public void run() {
for(int i =0 ; i < 5; i++) {
System.out.println("this is "+Thread.currentThread().getName()+"'s round "+i);
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
//匿名内部类构造线程,实现Runnable
new Thread(new Runnable() {
@Override
public void run() {
for(int i =0 ; i < 5; i++) {
System.out.println("this is "+Thread.currentThread().getName()+"'s round "+i);
}
}
}).start();
//输出main线程的信息
for(int i =0 ; i < 5; i++) {
System.out.println("this is "+Thread.currentThread().getName()+"'s round "+i);
}
}
}
result:
this is Thread-0's round 0
this is main's round 0
this is main's round 1
this is main's round 2
this is main's round 3
this is main's round 4
this is Thread-1's round 0
this is Thread-1's round 1
this is Thread-1's round 2
this is Thread-1's round 3
this is Thread-1's round 4
this is Thread-0's round 1
this is Thread-0's round 2
this is Thread-0's round 3
this is Thread-0's round 4
线程同步的三种方法(以售票为例),包括同步代码块、同步方法、锁
package xuexi1;
public class Lock1 implements Runnable{
//模拟买票系统,实现线程同步安全的三种方法
int ticket = 100; //初始票
Object o = new Object(); //随便创建一个Object对象作为锁对象,注意不能在run内部
//创建,因为需要每个线程公用一个锁对象
@Override
public void run() {
//1.利用同步代码块实现
while(true) {
synchronized(o) {
if(ticket>0) {
//模拟一个出票时间
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//输出信息,并出票
System.out.println(Thread.currentThread().getName()+" sold ticket "+ticket--);
}
}
}
}
}
package xuexi1;
public class Lock2 implements Runnable{
//模拟买票系统,实现线程同步安全的三种方法
int ticket = 100; //初始票
//2.利用同步方法来实现
public synchronized void sell() {
if(ticket>0) {
//模拟一个出票时间
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//输出信息,并出票
System.out.println(Thread.currentThread().getName()+" sold ticket "+ticket--);
}
}
@Override
public void run() {
while(true) {
sell();
}
}
}
package xuexi1;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Lock3 implements Runnable{
//模拟买票系统,实现线程同步安全的三种方法
int ticket = 100; //初始票
Lock lock = new ReentrantLock();
//3.利用Lock锁实现
@Override
public void run() {
while(true) {
lock.lock();
if(ticket>0) {
//模拟一个出票时间
try {
Thread.currentThread().sleep(100);
//输出信息,并出票
System.out.println(Thread.currentThread().getName()+" sold ticket "+ticket--);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock(); //这样的话,无论是否抛出异常,都会释放锁
}
}
}
}
}
主系统函数:
package xuexi1;
public class TestLock {
//模拟出票系统
//构建三个子线程
public static void main(String[] args) {
// //test Lock1
// Lock1 lock1 = new Lock1();
// new Thread(lock1).start();
// new Thread(lock1).start();
// new Thread(lock1).start();
// //test Lock2
// Lock2 lock2 = new Lock2();
// new Thread(lock2).start();
// new Thread(lock2).start();
// new Thread(lock2).start();
//test Lock3
Lock3 lock3 = new Lock3();
new Thread(lock3).start();
new Thread(lock3).start();
new Thread(lock3).start();
}
}
result:
Thread-0 sold ticket 100
Thread-0 sold ticket 99
Thread-0 sold ticket 98
Thread-0 sold ticket 97
Thread-0 sold ticket 96
Thread-0 sold ticket 95
Thread-0 sold ticket 94
Thread-1 sold ticket 93
...
Thread-0 sold ticket 5
Thread-1 sold ticket 4
Thread-1 sold ticket 3
Thread-2 sold ticket 2
Thread-2 sold ticket 1
等待唤醒简单案例
package xuexi1;
public class WaitAndNotify {
//wait() and notify()
public static void main(String[] args) {
//首先需要建立一个锁对象,因为wait和notify都应该针对同一个锁对象
Object lock = new Object();
//创建wait()线程
new Thread() {
@Override
public void run() {
//用同步代码块来实现
synchronized(lock) {
System.out.println("我要休息了...");
try {
lock.wait(); //加个lock吧
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //进入等待状态
System.out.println("休息完毕!"); //被唤醒后
}
}
}.start();
//创建唤醒线程
new Thread() {
@Override
public void run() {
synchronized(lock) { //注意,两个同步代码块用的是同一个锁对象
System.out.println("我要叫醒你了哦!");
lock.notify(); //同样加个lock吧,若有多个就是随机唤醒一个
//lock.notifyAll(); //若有多个可能的wait()可用这个
}
}
}.start();
}
}
result:
我要休息了...
我要叫醒你了哦!
休息完毕!
利用等待-唤醒机制有效的实现包子铺和客户之间的通信协调
包子类:
package xuexi1;
public class Baozi {
//担任包子类
public boolean state = false; //true表示有包子
}
包子铺类:
package xuexi1;
public class BaoziPu extends Thread{
//担任包子铺线程
//先把包子引进来
Baozi baozi;
//需要一个构造函数把baozi引进来,这样才能与BaoziEat共享同一个Baozi对象
public BaoziPu(Baozi baozi) {
this.baozi = baozi;
}
@Override
public void run() {
while(true) {
synchronized(baozi) { //以包子为锁对象
//若已有包子,等待
if(baozi.state) {
try {
baozi.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//若被唤醒了,即包子了
System.out.println("开始生产包子...");
baozi.state = true;
//唤醒吃包子的人
baozi.notify();
}
}
}
}
吃包子的人类:
package xuexi1;
public class BaoziEat extends Thread{
//担任吃包子的人线程
Baozi baozi;
//需要一个构造函数把baozi引进来,这样才能与BaoziEat共享同一个Baozi对象
public BaoziEat(Baozi baozi) {
this.baozi = baozi;
}
@Override
public void run() {
while(true) { //while循环记得开!!
synchronized (baozi) {
//若无包子,则等待
if(!baozi.state) {
try {
System.out.println("等待包子中...");
baozi.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//有包子了
System.out.println("有包子了,开吃!");
baozi.state = false;
System.out.println("吃光了,快做");
baozi.notify();
}
}
}
}
总流程类
package xuexi1;
public class BaoziSystem {
//担任总系统
public static void main(String[] args) {
Baozi baozi = new Baozi();
new BaoziPu(baozi).start();
new BaoziEat(baozi).start();
}
}
创建线程池Thread-pool,并提交三个任务
package xuexi1;
public class Task implements Runnable{
//0.使用Runnable创建一个线程任务
int taskNumber =0;
public Task(int x) {
super();
taskNumber=x;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" task "+taskNumber);
}
}
package xuexi1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPool {
//测试线程池
public static void main(String[] args) {
//1.生成线程池,建立一个size为10的线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
//2.创建三个不同的任务
Task r1 = new Task(1);
Task r2 = new Task(2);
Task r3 = new Task(3);
//3.提交任务
Future f1 = pool.submit(r1);
Future f2 = pool.submit(r2);
Future f3 = pool.submit(r3);
//可以不用f1,f2,f3接着,但是这边蛮看看返回结果...
System.out.println(f1);
System.out.println(f2);
System.out.println(f3);
//4.关掉线程池,但不建议使用。不关的话,程序是一直在执行...
//pool.shutdown();
}
}
result:
java.util.concurrent.FutureTask@232204a1
java.util.concurrent.FutureTask@4aa298b7
java.util.concurrent.FutureTask@7d4991ad
pool-1-thread-2 task 2
pool-1-thread-1 task 1
pool-1-thread-3 task 3
lambda函数编程(同时与匿名函数对比)
首先实现三个接口,分别包含一个无参无返回、有参无返回、有参有返回的函数。而后分别用匿名函数和lambda函数来实现。
package xuexi1;
public interface Interface1 {
public void fun1(); //无参无返回
}
package xuexi1;
public interface Interface2 {
public void fun1(int x); //有参无返回
}
package xuexi1;
public interface Interface3 {
public int fun1(int x); //有参有返回
}
package xuexi1;
public class LambdaTest {
public static void main(String[] args) {
//1.1 用匿名函数构造无参无返回
outerFun1(new Interface1() {
@Override
public void fun1() {
System.out.println("用匿名内部类实现无参无返回");}
});
//1.2 用lambda函数构造无参无返回
outerFun1(() -> {
System.out.println("用lambda实现无参无返回");
});
//2.1 用匿名函数构造有参无返回
outerFun2(new Interface2(){
@Override
public void fun1(int x) {
System.out.println("用匿名内部类实现有参无返回。参数:"+x);
}
});
//2.2 用lambda构造有参无返回
outerFun2((int x) -> {
System.out.println("用lambda实现有参无返回。参数:"+x);
});
//3.1 用匿名函数构造有参有返回
outerFun3(new Interface3() {
@Override
public int fun1(int x) {
System.out.print("用匿名内部类实现有参无返回。返回值:");
return x*2;
}
});
//3.2 用lambda构造有参有返回
outerFun3((int x)->{
System.out.print("用lambda实现有参无返回。返回值:");
return x*2;
});
//lambda略写~~~~
System.out.println("lambda略写验证--------");
//1.2 用lambda函数构造无参无返回
outerFun1(() -> System.out.println("用lambda实现无参无返回"));
//2.2 用lambda构造有参无返回
outerFun2((x) -> System.out.println("用lambda实现有参无返回。参数:"+x));
//3.2 用lambda构造有参有返回
outerFun3((x)->{
System.out.print("用lambda实现有参无返回。返回值:");
return x*2;
}); //此时不能省略{},因为方法实现体中不止一个语句
}
public static void outerFun1(Interface1 x) {
x.fun1();
};
public static void outerFun2(Interface2 x) {
x.fun1(100);
};
public static void outerFun3(Interface3 x) {
System.out.println(x.fun1(100));
};
}
result:
用匿名内部类实现无参无返回
用lambda实现无参无返回
用匿名内部类实现有参无返回。参数:100
用lambda实现有参无返回。参数:100
用匿名内部类实现有参无返回。返回值:200
用lambda实现有参无返回。返回值:200
lambda略写验证--------
用lambda实现无参无返回
用lambda实现有参无返回。参数:100
用lambda实现有参无返回。返回值:200
浙公网安备 33010602011771号