首页 > 其他分享 >经典多线程题目

经典多线程题目

时间:2023-10-15 15:23:14浏览次数:33  
标签:题目 Thread int class 线程 经典 new 多线程 public

1.三种线程按顺序执行

public class Test1 {
//    private static Logger log = Logger.getLogger(Test2.class);

    public static void main(String[] args) throws InterruptedException {
        //创建三个线程按照线程a,b,c执行
        Thread a = new PrintThread();
        Thread b = new PrintThread();
        Thread c = new PrintThread();
        a.setName("Thread-a");
        b.setName("Thread-b");
        c.setName("Thread-c");

        a.start();
        a.join();

        b.start();
        b.join();

        c.start();
        c.join();

    }

    public static class PrintThread extends Thread{

        @Override
        public void run() {
            super.run();
            System.out.println(Thread.currentThread().getName());
        }
    }
}
按序打印

  通过join()方法使得哪个线程调用join()方法,哪个线程执行完才能执行后续线程

2.两个线程轮流打印数字,直到100

public class Test2 {

    private static final Object lock = new Object();
    private static int count = 0;

    public static void main (String[] args) {
        //满足条件进入计算,可使得其他线程满足计算后的条件,不满足则等待
        new Thread(new PrintThread(0), "a").start();
        new Thread(new PrintThread(1), "b").start();
    }

    static class PrintThread implements Runnable{

        private int threadId;

        private PrintThread(int threadId){
            this.threadId = threadId;
        }
        @Override
        public void run() {
            synchronized (lock){
                while(count <= 100){
                    if(count%2 == threadId){//条件判断,结合wait和notifyAll
                        log.info(Thread.currentThread().getName()+"------"+count);
                        count++;
                        lock.notifyAll();
                    }else{
                        try {
                            lock.wait();
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}
数字交替打印

  通过加锁的方式保证线程同步访问共享资源,通过条件变量调用notifyAll()方法获取锁通知线程执行,调用wait方法释放锁进入等待状态

3.交替打印ABC

public class Test3 {

    public static void main(String[] args) {
        AwaitSignal as = new AwaitSignal(5);
        //休息室
        Condition a = as.newCondition();
        Condition b = as.newCondition();
        Condition c = as.newCondition();
        //
        new Thread(() -> {
            as.print("A", a, b);
        }).start();
        new Thread(() -> {
            as.print("B", b, c );
        }).start();
        new Thread(() -> {
            as.print("C", c, a);
        }).start();

        as.lock();
        try{
            System.out.println("开始...");
            a.signal();//需要主线程主动唤醒a线程
        }finally {
            as.unlock();
        }
    }

    //
    static class AwaitSignal extends ReentrantLock {
        private int loopNumber;

        public AwaitSignal(int loopNumber){
            this.loopNumber = loopNumber;
        }

        //参数1 打印内容,参数2 当前休息室,参数3:下一间休息室
        public void print(String str, Condition current, Condition next){
            for (int i = 0; i < loopNumber; i++) {
                lock();//继承ReentrantLock锁手动加锁,锁住一个休息室
                try {
                    current.await();//休息室等待
                    System.out.print(str);
                    next.signal();//进入下一个休息室
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    unlock();
                }
            }
        }
    }

}
交替打印ABC

  通过继承ReentrantLock类来对字符按照顺序打印,其中包含两个Condition(休息等待区),一个当前Condition,另一个下一个Condition。只有前一个执行完后通过notifyAll()方法获取锁通知下一个进行。

4.生产者消费者模式

public class Test4 {
    Logger logger = LoggerFactory.getLogger(ProducerAndCustomerTest.class);
    public static void main(String[] args) {
        MessageQueue queue = new MessageQueue(2);
        //创建三个生产者生产消息
        for (int i = 0; i < 3 ; i++) {
            int id = i;
            new Thread(() ->{
                queue.put(new Message(id, "值:"+id));
            }, "生产者" + i).start();
        }


        new Thread(() -> {
            while(true){
                try {
                    Thread.sleep(1);
                    queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"消费者").start();
    }
}

//消息队列类,java线程之间通信
class MessageQueue{
    Logger logger = LoggerFactory.getLogger(MessageQueue.class);
    //消息队列集合
    private LinkedList<Message> list = new LinkedList<>();
    //队列容量
    private int capacity;

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    //获取消息
    public Message take(){
        //检查对象是否为null
        synchronized (list){
            while(list.isEmpty()){
                try {
                    logger.info("队列为空,消费者等待消息生产");
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //从队列头部获取消息返回
            Message message = list.removeFirst();
            logger.info("已消费信息 {}", message);
            //消费完通知
            list.notifyAll();
            return message;
        }
    }

    //存入消息
    public void put(Message message){
        synchronized (list){
            //检查队列是否已满
            while (list.size() == capacity){
                try {
                    logger.info("队列已满,生产者线程等待");
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //将消息加入队列尾部
            list.addLast(message);
            logger.info("已生产信息 {}", message);
            list.notifyAll();//生产完通知
        }
    }
}


final class Message{//安全
    private int id;
    private Object value;

    public Message(int id, Object value) {
        this.id = id;
        this.value = value;
    }

    public int getId() {//只有读安全,无法改变值
        return id;
    }

    public Object getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", value=" + value +
                '}';
    }
}
提供者和消费者模式

  创建两类线程,一类生产者线程,另一类消费者线程。通过生产者线程生产消息并加入消息队列中,另一类消费者线程从消息队列中取出消息消费。通过消息队列的take()判断当消息集合为空时调用wait等待生产者生产,不为空时从消息集合取消息,并通过notifyAll()方法通知生产者消息消费完。通过消息队列的put()判断当消息集合为满时调用wait等待消费者,不满时向消息集合加入消息,并通过notifyAll()方法通知生产者消费消息。

标签:题目,Thread,int,class,线程,经典,new,多线程,public
From: https://www.cnblogs.com/kzf-99/p/17765467.html

相关文章

  • #1 题目
    题目题(额头)目(眼睛),文章的眉目之间。传达文章的意思。文章标题可能有一些词性:名词反复出现频率最高的一个名词。好处是什么?不止一次出现,连成线,构成文章线索就出了一次,凭啥?说明全文围绕它展开。出现多次,但每一次含义都不同。一语双关多关。动词题目不能是纯动词(打、听、......
  • 锁+多线程
     互斥锁mutex:保证共享数据操作的完整性,保证在任一时刻只能有一个线程访问对象。锁有两个操作。一个P操作(上锁),一个V操作(解锁)。P和V都是原子操作,就是在执行P和V操作时,不会被插队。锁一般使用信号量来实现的,mutex其实就是信号量=1。互斥量就是同一时间能够分给一个人,即S=1。S=......
  • 关于堆栈的讲解(我见过的最经典的) 转载
    关于堆栈的讲解(我见过的最经典的)转载 转:https://blog.csdn.net/yingms/article/details/53188974这是一篇转发的文章,我对他进行了格式化而已,原文出处不详。一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)—由编译器自......
  • python多线程with方式加锁
    python多线程with方式加锁"""pythonTreading中的Lock模块提供了加锁和释放锁的方法,分别是acquire()和release().这两个方法可以搭配python的with语句使用."""#示例fromthreadingimportLock​temp_lock=Lock()​withtemp_lock: print(temp_lock) #输出是<locked......
  • 多线程逆向
    一.资料检索以及归纳XDBG调试时默认是只运行下断调试的线程其它线程处于暂停挂起状态属于单线程调试。打开线程窗口可以查看线程挂起计数(+号-号快捷键可以挂起恢复线程)双击线程可进入选择线程,如果要调试指定线程的话我的理解是应该在线程代码中下断(线程的各种系统CALL),线程会自......
  • 机器学习经典教材《模式识别与机器学习》,Pattern Recognition and Machine Learning,PR
     微软剑桥研究院实验室主任ChristopherBishop的经典著作《模式识别与机器学习》,PatternRecognitionandMachineLearning,简称PRML,被微软“开源”了。  =================================  本书介绍&下载页:(书的介绍页面)https://www.microsoft.com/en-us/research......
  • 弗洛伊德(Floyd's)算法—解决最短路径经典算法
    弗洛伊德算法(Floyd'salgorithm)是一种用于解决图中最短路径问题的经典算法。由美国计算机科学家罗伯特·弗洛伊德于1962年提出,该算法通过动态规划的思想,在图中寻找任意两个节点之间的最短路径,具有广泛的应用。本文将详细介绍弗洛伊德算法的原理、实现细节以及应用案例。四、复杂度......
  • C++ - 多线程之线程管理函数
    1.获取线程id函数get_id()的使用该函数在命名空间std::this_thread下。作用是获取当前线程的id。#include<iostream>#include<thread>usingnamespacestd;//No.1get_id()获取线程idvoidthreadFunc(){ cout<<"get_id()子线程id:"<<this_thread::get_id(......
  • C++ - 多线程之带返回值的线程处理函数
    1.使用async函数创建线程1.1使用步骤使用async函数启动一个异步任务(创建线程,并且执行线程处理函数),返回future对象通过future对象中get()方法获取线程处理函数的返回值1.2基本数据类型作为返回值#include<iostream>#include<thread>#include<future>using......
  • C++ - 多线程之线程同步
    1.多线程的并发问题线程间为什么需要同步?直接来看一个例子:inta=0;voidfoo(){ for(inti=0;i<10000000;++i) { a+=1; }}intmain(){ clock_tstart,end; start=clock(); threadt1(foo); threadt2(foo); t1.join(); t2.join(); end=clock();......