当前位置:网站首页>多线程习题
多线程习题
2022-06-23 09:33:00 【Linging_24】
- 三个线程t1、t2、t3。确保三个线程,t1执行完后t2执行,t2执行完后t3执行。
使用Semaphore
- 三个线程t1、t2、t3。确保三个线程,t1,t2执行完,t3再执行。
public class Test01 {
private Object obj = new Object();
//线程1、2执行完后,再执行线程3,使用wait()、notify()
public static void main(String[] args) {
new Test01().exec();
}
public void exec(){
new Thread(()->{
synchronized (obj){
try {
obj.wait();
System.out.println("线程:"+Thread.currentThread().getName()+"=>执行了....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},String.valueOf(3)).start();
for (int i = 0; i < 2; i++) {
final int tmp = i;
new Thread(()->{
synchronized (obj){
System.out.println("线程:" + Thread.currentThread().getName() + "=>执行了....");
if(tmp == 1)
obj.notify();
}
},String.valueOf(i+1)).start();
}
}
}
public class Test02 {
private CountDownLatch latch =new CountDownLatch(2);
//线程1、2执行完后,再执行线程3,使用CountDownLatch
public static void main(String[] args) {
new Test02().exec();
}
public void exec(){
new Thread(()->{
try {
latch.await();
System.out.println(Thread.currentThread().getName() + "=>执行了....");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程3").start();
for (int i = 0; i < 2; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "=>执行了....");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
},String.valueOf("线程" + (i+1))).start();
}
}
}
class T1 implements Runnable{
@Override
public void run() {
System.out.println("1");
}
}
class T2 implements Runnable{
Thread father;
public void set(Thread father) {
this.father = father;
}
@Override
public void run() {
try {
father.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2");
}
}
class T3 implements Runnable{
Thread father;
public void set(Thread father) {
this.father = father;
}
@Override
public void run() {
try {
father.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3");
}
}
public class Test {
//使用join
public static void main(String[] args) {
T1 task1 = new T1();
T2 task2 = new T2();
T3 task3 = new T3();
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task2);
Thread t3 = new Thread(task3);
task2.set(t1);
task3.set(t1);
t1.start();
t2.start();
t3.start();
}
}
- 现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。
public class Test {
/** * 现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志, * 请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象; * 思路1: * 1.将16个日志对象放到阻塞队列中 * 2.开启4个线程从阻塞队列中拿日志对象执行 * 3.日志对象执行时间为 1s * 4.此方式线程会一直跑,阻塞 * * 思路2: * 1.创建具有4个核心线程的线程池 * 2.在阻塞队列中加入16个打印日志对象的任务 * 3.执行线程池的任务 * 4.日志对象执行时间为 1s * 5.此方式线程会销毁 * */
public static void main(String[] args) {
test01(); //思路1实现
//test02(); //思路2实现
}
private static void test01() {
long start = System.currentTimeMillis();
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
//将16个日志对象放入阻塞队列中
for (int i = 1; i <= 16; i++) {
try {
queue.put("日志对象:" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开启4个线程从阻塞队列中拿日志对象执行
for (int i = 0; i < 4; i++) {
new Thread(()->{
while(true){
try {
String log = queue.take();
printLog(log);
long end = System.currentTimeMillis();
System.out.println((end-start) + "ms");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
public static void test02(){
long start = System.currentTimeMillis();
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(16);
//创建具有四个核心线程的线程池
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
4,
4,
3000,
TimeUnit.MILLISECONDS,
queue,
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
//将16个打印日志对象的任务放入阻塞队列中
for (int i = 0; i < 16; i++) {
final String tmp = "任务" + (i+1) + "";
poolExecutor.execute(()->{
printLog(tmp);
});
}
poolExecutor.shutdown();
//判断线程池的任务是否执行完毕
while(true){
long end = System.currentTimeMillis();
if(poolExecutor.isTerminated()){
System.out.println((end-start) + "ms");
break;
}
}
}
public static void printLog(String log){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "===>打印日志=========>" + log);
}
}
- 10个线程同步执行10个任务
public class Test2 {
/** * 10个线程同步执行10个任务 * 方式1:synchronized * 方式2:Lock * 方式3:Semaphore * @param args */
public static void main(String[] args) {
//test01(); //synchronized
//test02(); //Lock
test03(); //Semaphore
}
public static void test01(){
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);
//往阻塞队列中加入任务
for (int i = 0; i < 10; i++) {
try {
queue.put("任务:" + (i+1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//10个线程顺序执行任务
for (int i = 0; i < 10; i++) {
new Thread(()->{
synchronized (queue){
try {
String task = queue.take();
executeTask(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
public static void test02(){
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
Lock lock = new ReentrantLock();
//往阻塞队列中加入任务
for (int i = 0; i < 10; i++) {
try {
queue.put("任务:" + (i+1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//10个线程顺序执行任务
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
lock.lock();
String task = queue.take();
executeTask(task);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}).start();
}
}
public static void test03(){
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);
Semaphore semaphore = new Semaphore(1);
//往阻塞队列中加入任务
for (int i = 0; i < 10; i++) {
try {
queue.put("任务:" + (i+1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//10个线程顺序执行任务
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
semaphore.acquire();
String task = queue.take();
executeTask(task);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
public static void executeTask(String task){
System.out.println(Thread.currentThread().getName() + "==>" + task);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 10个商品被20个用户抢购,如何让商品正常卖出,不会超卖:
public class Test03 {
//10个商品
private int goods = 10;
public static void main(String[] args) {
new Test03().exec();
}
public synchronized void exec(){
for (int i = 0; i < 20; i++) {
new Thread(()->{
if(goods > 0){
System.out.println(Thread.currentThread().getName() + ",抢到了第 " + goods-- + " 张票");
}
},String.valueOf("用户" + (i+1))).start();
}
}
}
- 生产者消费者问题
//数据
class Data{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
//生产者
class Producer implements Runnable{
private Data data;
public Producer(Data data) {
this.data = data;
}
@Override
public void run() {
int i = 0;
while(true) {
synchronized(data){
//如果数据为空,则生产数据
if(data.getMessage() == null) {
data.setMessage(i + "");
System.out.println("生产:" + i);
i++;
}
//生产完数据通知消费者消费
data.notify();
//生产者挂起
try {
data.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//消费者
class Consumer implements Runnable{
private Data data;
public Consumer(Data data) {
this.data = data;
}
public void run() {
while(true) {
synchronized(data) {
//如果数据不为空,则消费
if(data.getMessage() != null) {
System.out.println("消费:" + data.getMessage());
data.setMessage(null);
}
//消费完,通知生产者进行生产
data.notify();
//消费者挂起
try {
data.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Test {
public static void main(String[] args) {
Data data = new Data();
Producer p = new Producer(data);
Consumer c = new Consumer(data);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
- 优雅的停止线程
class Task implements Runnable{
private volatile boolean isFlag = true;
public void stop() {
this.isFlag = false;
}
public void run() {
int i = 0;
while(isFlag) {
System.out.println(i++);
}
}
}
public class Test {
//使用标志位
public static void main(String[] args) throws InterruptedException {
Task task = new Task();
Thread t = new Thread(task);
t.start();
TimeUnit.SECONDS.sleep(1);
task.stop();
}
}
class Task implements Runnable{
public void run() {
int i = 0;
while(true) {
Thread t = Thread.currentThread();
if(t.isInterrupted()) {
//判断是否处于中断状态
break;
}
System.out.println(i++);
}
}
}
public class Test {
//使用interrupt
public static void main(String[] args) throws InterruptedException {
Task task = new Task();
Thread t = new Thread(task);
t.start();
TimeUnit.SECONDS.sleep(1);
t.interrupt(); //中断
}
}
- 多线程循环顺序打印:ABABABABAB,线程A打印A,线程B打印B。
使用Object.wait()和notifyAll() 或者Lock + Condition
- 多线程循环顺序打印:0102030405,线程0打印0,线程1打印奇数,线程2打印偶数
使用Object.wait()和notifyAll() 或者Lock + Condition
代码后续更新。。。
shutdown和shutwdown的区别:
- shutdown只是将线程池的状态设置为SHUTWDOWN状态,正在执行的任务会继续执行下去,没有被执行的则中断。
- shutdownNow则是将线程池的状态设置为STOP,正在执行的任务则被停止,没被执行任务的则返回。
isShutDown:
- isShutDown当调用shutdown()或shutdownNow()方法后返回为true。
- isTerminated当调用shutdown()方法后,并且所有提交的任务完成后返回为true;
- isTerminated当调用shutdownNow()方法后,成功停止后返回为true;
边栏推荐
猜你喜欢

Redis learning notes - client communication protocol resp

What is BFC? What problems can BFC solve

Typora set up image upload service
![[网鼎杯 2020 青龙组]AreUSerialz](/img/38/b67f7a42abec1cdaad02f2b7df6546.png)
[网鼎杯 2020 青龙组]AreUSerialz

Aiming at the overseas pet market, "grasshand" has developed an intelligent tracking product independent of mobile phones | early project

Wechat applet: click the button to switch frequently, overlap the custom markers, but the value does not change
Redis学习笔记—数据类型:哈希(hash)
Redis学习笔记—单个键管理

16. system startup process

Learn SCI thesis drawing skills (f)
随机推荐
#gStore-weekly | gStore源码解析(四):安全机制之黑白名单配置解析
Lua的基本使用
Pizza ordering design - simple factory model
C#之Lambda不得不说的用法
Redis learning notes - AOF of persistence mechanism
[plugin:vite:import-analysis]Failed to resolve import “@/“ from ““.Does the file exist
玩转NanoPi 2 裸机教程编程-01点亮User LED难点解析
Cookie和Session入门
RGB and CMYK color modes
【CTF】 2018_rop
[SUCTF 2019]CheckIn
Learn SCI thesis drawing skills (E)
Best time to buy and sell stock II
薄膜干涉数据处理
Precautions for map interface
嵌入式系统概述(学习笔记)
Redis learning notes RDB of persistence mechanism
一个采用直接映射方式的32KB缓存......存储器课后习题
也无风雨也无晴
Structure binary tree from preorder and inorder traversal for leetcode topic analysis