花几千上万学习Java,真没必要!(四十三)

1、实现Runna接口创建线程:

测试代码:

package test.runnable;
public class MultiThreadedCalculations {  
	  
    // 计算0到n的整数和  
    static class SumTask implements Runnable {  
        private int n;  
  
        public SumTask(int n) {  
            this.n = n;  
        }  
  
        @Override  
        public void run() {  
            int sum = 0;  
            for (int i = 0; i <= n; i++) {  
                sum += i;  
            }  
            System.out.println(Thread.currentThread().getName() + " 计算0到" + n + "的整数和结果为: " + sum);  
        }  
    }  
  
    // 计算0到n的阶乘  
    static class FactorialTask implements Runnable {  
        private int n;  
  
        public FactorialTask(int n) {  
            this.n = n;  
        }  
  
        @Override  
        public void run() {  
            long factorial = 1;  
            for (int i = 1; i <= n; i++) {  
                factorial *= i;  
            }  
            System.out.println(Thread.currentThread().getName() + " 计算0到" + n + "的阶乘结果为: " + factorial);  
        }  
    }  
  
    // 计算0到n的平方和  
    static class SquareSumTask implements Runnable {  
        private int n;  
  
        public SquareSumTask(int n) {  
            this.n = n;  
        }  
  
        @Override  
        public void run() {  
            int sum = 0;  
            for (int i = 0; i <= n; i++) {  
                sum += i * i;  
            }  
            System.out.println(Thread.currentThread().getName() + " 计算0到" + n + "的平方和结果为: " + sum);  
        }  
    }  
  
    public static void main(String[] args) {  
        // 创建线程任务  
        Runnable sumTask = new SumTask(100);  
        Runnable factorialTask = new FactorialTask(8);  
        Runnable squareSumTask = new SquareSumTask(12);  
  
        // 创建并启动线程  
        Thread sumThread = new Thread(sumTask, "整数和线程");  
        Thread factorialThread = new Thread(factorialTask, "阶乘线程");  
        Thread squareSumThread = new Thread(squareSumTask, "平方和线程");  
  
        // 启动线程  
        sumThread.start();  
        factorialThread.start();  
        squareSumThread.start();  
    }  
}

2、同步代码块解决数据安全的问题:

测试代码:

package test.runnable;
//同步代码块
public class SafeCounter {  
    private int count = 0;  
    // 定义一个对象,通常可以使用`this`或者当前类的某个私有对象作为锁  
    // 使用一个私有的final对象  
    private final Object lock = new Object();  
  
    // 增加计数的方法,使用同步代码块  
    public void increment() {  
        synchronized (lock) {  
            count++; // 只有获得了lock锁的线程才能执行这行代码  
        }  
    }  
  
    // 获取计数的当前值
    public int getCount() {  
        return count;  
    }  
  
    // 测试方法,创建多个线程来增加计数并打印最终结果  
    public static void main(String[] args) throws InterruptedException {  
        SafeCounter counter = new SafeCounter();  
  
        // 创建多个线程来增加计数  
        Thread[] threads = new Thread[10];  
        for (int i = 0; i < threads.length; i++) {  
            threads[i] = new Thread(() -> {  
                for (int j = 0; j < 1000; j++) {  
                    counter.increment();  
                }  
            });  
            threads[i].start();  
        }  
  
        // 等待所有线程完成  
        for (Thread t : threads) {  
            t.join();  
        }  
  
        // 打印最终结果,计数是准确的。  
        System.out.println("Final count: " + counter.getCount());  
    }  
}

3、同步方法解决数据安全的问题:

package test.runnable;
public class SafeCounterTest {  
    private int count = 0;  
  
    // 同步方法,确保一次只有一个线程能执行该方法  
    public synchronized void increment() {  
        count++;  
    }  
  
    // 获取计数的当前值
    public int getCount() {  
        return count;  
    }  
  
    // 测试方法,创建多个线程增加计数并打印最终结果  
    public static void main(String[] args) throws InterruptedException {  
        SafeCounterTest counter = new SafeCounterTest();  
  
        // 创建多个线程增加计数  
        Thread[] threads = new Thread[10];  
        for (int i = 0; i < threads.length; i++) {  
            final int threadNum = i;  
            threads[i] = new Thread(() -> {  
                for (int j = 0; j < 1000; j++) {  
                    counter.increment(); // 调用同步方法  
                }  
                // 添加打印语句观察每个线程的执行情况
                 System.out.println("Thread " + threadNum + " finished");  
            });  
            threads[i].start();  
        }  
  
        // 等待所有线程完成  
        for (Thread t : threads) {  
            t.join();  
        }  
  
        // 打印最终结果  
        System.out.println("Final count: " + counter.getCount());  
    }  
}

4、同步方法和静态同步方法的锁对象。

package test.runnable;
//同步方法和静态同步方法的锁对象。
public class SyncMethodDemo {  
  
    // 实例变量  
    private int count = 0;  
  
    // 实例同步方法  
    public synchronized void instanceSyncMethod() {  
        for (int i = 0; i < 5; i++) {  
            count++;  
            try {  
                // 耗时操作  
                Thread.sleep(100);  
            } catch (InterruptedException e) {  
                Thread.currentThread().interrupt();  
            }  
        }  
        System.out.println(Thread.currentThread().getName() + " 完成实例同步方法, count = " + count);  
    }  
  
    // 静态同步方法  
    public static synchronized void staticSyncMethod() {  
 
        int staticCount = 0;  
        for (int i = 0; i < 5; i++) {  
            staticCount++;  
            try {  
                // 耗时操作  
                Thread.sleep(100);  
            } catch (InterruptedException e) {  
                Thread.currentThread().interrupt();  
            }  
        }  
        System.out.println(Thread.currentThread().getName() + " 完成静态同步方法, staticCount = " + staticCount);  
    }   
  //实例同步方法:instanceSyncMethod 方法通过 this 锁对象进行同步.
  //如果两个线程在相同的 SyncMethodDemo 实例上调用此方法,将不能同时执行该方法。
  //在不同的实例上调用,可以并行执行。

  //静态同步方法:staticSyncMethod 方法,通过类的 Class 对象进行同步。
  //无论在哪个实例上调用此方法,所有线程都将竞争同一把锁,因此一次只能有一个线程执行该方法。
  //main 方法中,创建了四个线程来演示同步方法的行为。
  //两个线程调用实例同步方法,两个线程调用静态同步方法。
    public static void main(String[] args) {  
        SyncMethodDemo instance1 = new SyncMethodDemo();  
        SyncMethodDemo instance2 = new SyncMethodDemo();  
  
        // 创建并启动线程,使用同步方法。  
        Thread t1 = new Thread(() -> instance1.instanceSyncMethod(), "Thread-1");  
        Thread t2 = new Thread(() -> instance2.instanceSyncMethod(), "Thread-2");  
  
        // 静态同步方法,不需要实例  
        Thread t3 = new Thread(SyncMethodDemo::staticSyncMethod, "Thread-3");  
        Thread t4 = new Thread(SyncMethodDemo::staticSyncMethod, "Thread-4");  
  
        // 启动线程  
        t1.start();  
        t2.start();  
        t3.start();  
        t4.start();  
  
        // 同步方法和静态同步方法使用的是不同的锁对象(实例的`this`和类的`Class`对象)  
    }  
}  

5、 使用ReentrantLock作为锁,解决数据安全的问题:

package test.runnable;
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
  
public class SafeCounterWithLock {  
    private int count = 0;  
    // 使用ReentrantLock作为锁  
    private final Lock lock = new ReentrantLock();  
  
    // 使用Lock锁保护count的递增  
    public void increment() {  
        lock.lock(); // 获取锁  
        try {  
            count++;  
        } finally {  
            lock.unlock(); // 释放锁,无论是否发生异常  
        }  
    }  
  
    // 获取计数的当前值
    public int getCount() {  
        return count;  
    }  
  
    // 创建多个线程增加计数并打印最终结果  
    public static void main(String[] args) throws InterruptedException {  
        SafeCounterWithLock counter = new SafeCounterWithLock();  
  
        // 创建多个线程增加计数  
        Thread[] threads = new Thread[10];  
        for (int i = 0; i < threads.length; i++) {  
            threads[i] = new Thread(() -> {  
                for (int j = 0; j < 1000; j++) {  
                    counter.increment();  
                }  
            });  
            threads[i].start();  
        }  
  
        // 等待所有线程完成  
        for (Thread t : threads) {  
            t.join();  
        }  
  
        // 打印最终结果  
        System.out.println("Final count: " + counter.getCount());  
    }  
}

6、某知识竞赛共有100道题目,有4人抢答,所有参与者均有同等的机会抢答到其中的25道题目。

测试代码1:

package test.runnable;
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;  

//抢占式线程,不带同步锁,4个参赛者并不是机会均等。  
public class QuizContest {  
  
    private static final int TOTAL_QUESTIONS = 100;  
    private final AtomicInteger currentQuestion = new AtomicInteger(1);  
  
    public static void main(String[] args) {  
        QuizContest contest = new QuizContest();  
        ExecutorService executor = Executors.newFixedThreadPool(4);  
  
        // 创建并启动4个参赛者线程  
        for (int i = 1; i <= 4; i++) {  
            final int contestantId = i;  
            executor.submit(() -> {  
                while (true) {  
                    int nextQuestion = contest.attemptAnswer();  
                    if (nextQuestion == 0) {  
                        // 所有题目都已被抢答完毕  
                        break;  
                    }  
                    // 假设抢答成功,打印信息  
                    System.out.println("参赛者 " + contestantId + " 抢答了题目 " + nextQuestion);  
                }  
            });  
        }  
  
        // 关闭ExecutorService,并等待所有任务完成  
        executor.shutdown();  
        try {  
            if (!executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {  
                executor.shutdownNow();  
            }  
        } catch (InterruptedException e) {  
            executor.shutdownNow();  
            Thread.currentThread().interrupt();  
        }  
  
        System.out.println("所有题目抢答完毕!");  
    }  
  
    // 尝试抢答题目,如果成功则返回题目编号,如果所有题目都已被抢答则返回0  
    private int attemptAnswer() {  
        int current = currentQuestion.get();  
        if (current > TOTAL_QUESTIONS) {  
            // 所有题目都已被抢答完毕  
            return 0;  
        }  
        // 尝试更新当前题目编号  
        if (currentQuestion.compareAndSet(current, current + 1)) {  
            // 抢答成功,返回题目编号  
            return current;  
        }  
        // 抢答失败,可能是其他线程已经抢答了这道题目    
        return 0; 
    }  
}  

运行结果如下:

测试代码2:

package test.runnable;
public class QuizCompetition {  
    private int remainingQuestions = 100;  
    private final Object lock = new Object();  
  
    // 同步锁实现抢答题目方法,使每个参赛者具有相等的抢答数量。  
    public synchronized void answerQuestion(int playerIndex) throws InterruptedException {  
        // 等待直到有剩余题目  
        while (remainingQuestions <= 0) {  
            lock.wait(); // 使用synchronized方法的隐式锁。
        }  
  
        // 检查当前是否还有剩余题目供参与者抢答  
        if (remainingQuestions > 0) {  
            // 每个参与者都记录自己的抢答次数(在实际应用中,通过某种共享数据结构实现)  
            // 打印并减少剩余题目数  
            System.out.println("参与者 " + (playerIndex + 1) + " 抢答了题目 #" + (101 - remainingQuestions));  
            remainingQuestions--;  
  
            // 唤醒其他等待的线程
            // lock.notifyAll(); // 
            Thread.sleep(10); // 假设抢答之间有微小的间隔  
        }  
    }  
  
    public static void main(String[] args) {  
        QuizCompetition competition = new QuizCompetition();  
  
        // 创建四个线程表示四个参与者  
        for (int i = 0; i < 4; i++) {  
            final int playerIndex = i;  
            new Thread(() -> {  
                try {  
                    for (int j = 0; j < 25; j++) {  
                        competition.answerQuestion(playerIndex);  
                    }  
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt();  
                }  
            }).start();  
        }  
    }  
}  

运行结果如下:

7、生产者消费者模式:

 

测试代码:

package test.runnable;
public class ProducerConsumerExample {  
    private static final int BUFFER_SIZE = 10;  
    private final int[] buffer;  
    private int count = 0;  
    private int head = 0;  
    private int tail = 0;  
  
    public ProducerConsumerExample(int size) {  
        this.buffer = new int[size];  
    }  
  
    // 生产者  
    public void produce(int item) throws InterruptedException {  
        synchronized (this) {  
            // 缓冲区满时等待  
            while (count == BUFFER_SIZE) {  
                wait();  
            }  
            // 生产产品  
            buffer[tail] = item;  
            System.out.println("Produced: " + item);  
            tail = (tail + 1) % BUFFER_SIZE;  
            count++;  
            // 通知消费者  
            notifyAll();  
        }  
    }  
  
    // 消费者  
    public int consume() throws InterruptedException {  
        synchronized (this) {  
            // 缓冲区空时等待  
            while (count == 0) {  
                wait();  
            }  
            // 消费产品  
            int item = buffer[head];  
            System.out.println("Consumed: " + item);  
            head = (head + 1) % BUFFER_SIZE;  
            count--;  
            // 通知生产者  
             notifyAll();  
            return item;  
        }  
    }  
  
    public static void main(String[] args) {  
        ProducerConsumerExample pc = new ProducerConsumerExample(BUFFER_SIZE);  
  
        // 生产者线程  
        Thread producer = new Thread(() -> {  
            for (int i = 0; i < 50; i++) {  
                try {  
                    pc.produce(i);  
                    Thread.sleep(1000); 
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt();  
                }  
            }  
        });  
  
        // 消费者线程  
        Thread consumer = new Thread(() -> {  
            for (int i = 0; i < 50; i++) {  
                try {  
                    pc.consume();  
                    Thread.sleep(1000);  
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt();  
                }  
            }  
        });  
  
        producer.start();  
        consumer.start();  
    }  
}

运行结果如下:

8、线程池:

package test.runnable;
//线程池(ThreadPool)是一种基于池化技术管理线程的技术,可以减少线程创建和销毁的开销,提高系统的响应速度。
//ExecutorService接口是最核心的接口。
//使用Executors工厂类创建线程池。
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;  
  
public class ThreadPoolDemo {  
  
    public static void main(String[] args) {  
        // 创建一个固定数量为5的线程池,同时最多有5个线程执行。  
        ExecutorService executorService = Executors.newFixedThreadPool(5);  
  
        // 使用lambda表达式或匿名内部类定义任务  
        for (int i = 0; i < 10; i++) {  
            int taskId = i;  
            executorService.submit(() -> {  
                // 耗时任务  
                try {  
                    Thread.sleep(1000);  
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt();  
                }  
                // 执行任务  
                System.out.println(Thread.currentThread().getName() + " 完成了任务 " + taskId);  
            });  
        }  
  
        // 关闭线程池,不会立即关闭线程池,而是不再接受新的任务,  
        // 它会等待所有已提交的任务(包括尚未开始执行的)完成后才终止。  
        executorService.shutdown();  
  
        try {  
            // 等待线程池中的任务全部完成  
            // 如果调用shutdownNow,方法会立即返回false,不再等待  
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  
                // 如果超时时间到了,但任务还没执行完,可以选择取消剩余的任务  
                executorService.shutdownNow();  
                       }  
        } catch (InterruptedException e) {  
            // 当前线程在等待过程中被中断  
            executorService.shutdownNow();  
            // 保留中断状态  
            Thread.currentThread().interrupt();  
        }  
  
        // 实际应用中,awaitTermination的调用可能会根据具体需求有所不同。  
        // 例如,在某些情况下,可能不需要等待所有任务完成,或者可能想要以不同的方式处理中断。  
    }  
}  

运行结果如下:

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值