JAVA多线程(二)
Synchronized的使用:
(一)synchronized: Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
当某个方法或者代码块被声明为”synchronized”后,保存数据的内存空间(例如堆内存)将保持被同步状态。这意味着:当一个线程获取锁并且执行到已被声明为synchronized的方法或者代码块时,该线程首先从主堆内存空间中读取该锁定对象的所有变化,以确保其在开始执行之前拥有最新的信息。在synchronized部分执行完毕,线程准备释放锁的时候,所有针对被锁定对象的修改都将为写入主堆内存中。这样其他线程在请求锁的时候就可以获取最新的信息。
(二)创建线程的三种方法:
1、继承Thread public class AddThread extends Thread{}
2、实现Runnable public class AScaleThread implements Runnable{}
3、建立线程池 ExecutorService service = Executors.newFixedThreadPool(2);
(三)Synchroized的经典生产者与消费者问题:
代码1:

package com.my.thread; public class NumFactory { public int num = 10; public int total = 20; //非同步方法 public void add(){ num = num+2; } public void scale(){ num--; } //同步方法 public synchronized void addSync(){ while(num > 20){ try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.notify(); num = num + 2; System.out.println("生产了两个。当前数量:==="+num); } public synchronized void scaleSync(){ while(num < 10){ try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.notify(); num--; System.out.println("消费了一个。当前数量:==="+num); } }

package com.my.thread; public class AddThread extends Thread{ public NumFactory factory; public AddThread(NumFactory factory) { this.factory = factory; } @Override public void run() { for (int i = 0; i < 10; i++) { factory.addSync(); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

package com.my.thread; public class AScaleThread implements Runnable{ public NumFactory factory; public AScaleThread(NumFactory factory) { this.factory = factory; } @Override public void run() { for (int i = 0; i < 20; i++) { factory.scaleSync(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

package com.my.thread; public class MainThread { public static void main(String[] args) { /*BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); new Thread(consumer).start(); new Thread(producer).start(); */ NumFactory factory = new NumFactory(); new Thread(new AScaleThread(factory)).start(); new AddThread(factory).start(); } }
代码2:
package com.my.thread; public class AddThread extends Thread{ public NumFactory factory; public AddThread(NumFactory factory) { this.factory = factory; } @Override public void run() { synchronized (factory) { while (factory.num > 20) { try { factory.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } factory.notify(); factory.add(); System.out.println("生产了两个,还剩下:==="+factory.num); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
package com.my.thread; public class MainThread { public static void main(String[] args) { /*BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); new Thread(consumer).start(); new Thread(producer).start(); */ NumFactory factory = new NumFactory(); for (int i = 0; i < 10; i++) { new Thread(new AScaleThread(factory)).start(); new AddThread(factory).start(); } } }
package com.my.thread; public class AScaleThread implements Runnable{ public NumFactory factory; public AScaleThread(NumFactory factory) { this.factory = factory; } @Override public void run() { synchronized (factory) { while (factory.num < 15) { try { factory.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } factory.notify(); factory.scale(); System.out.println("消费了一个,还剩下:==="+factory.num); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
代码3: 用BlockingQueue解决同步问题:

package com.my.thread; import java.util.concurrent.BlockingQueue; public class Producer implements Runnable{ BlockingQueue<String> block; public Producer(BlockingQueue<String> block){ this.block = block; } @Override public void run() { try { block.put(Thread.currentThread().getName()); System.out.println("放入到队列中:==="+Thread.currentThread().getName()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

package com.my.thread; import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable{ BlockingQueue<String> block; public Consumer(BlockingQueue<String> block){ this.block = block; } @Override public void run() { try { String take = block.take(); System.out.println("取出队列中的:==="+take); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.my.thread; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class MainThread { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); new Thread(consumer).start(); new Thread(producer).start(); } }
应该还有......
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人