线程数据共享与协作

本文深入探讨了Java中线程的数据共享与协作机制,包括synchronized关键字的使用,线程间如何通过对象锁实现串行运行,以及wait(), notify(), notifyAll()等方法在线程协作中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程间数据共享

并发运行:

线程中并发指一个时间段中多个线程都处于已启动但没有运行结束的状态。
多个线程之间默认并发运行,这种运行方式往往会出现交叉的情况。
如下例子:
在这里插入图片描述
在这里插入图片描述

串行运行:

使原本并发运行的多个线程实现串行运行,即多线程间同步执行,需要通过对象锁机制来实现,synchronized就是一个利用锁实现线程同步的关键字。
默认情况下,线程之间是交叉进行的(并发运行),下边用synchronized关键字实现线程之间数据共享,依次执行。
1,

public class T {
	public static void main(String[] args) {
		Object lock=new Object();//数据共享
		
		new CountThread1("线性1",lock).start();
		new CountThread1("线性2",lock).start();//记得就绪,调用start方法。默认情况下,线程之间交叉进行。
	}
}

class CountThread1 extends Thread{
	
	 Object lock;

	CountThread1(String name,Object lock){
		super(name);
		this.lock=lock;
	}

	@Override
	public void run() {
		
		 System.out.println(getName()+"~~~~~~~~~~");
		 synchronized (lock) {//synchronized为对象锁,添加了此行代码之后,将锁定包围在里边的代码,只有锁定该代码的线程可以执行里边代码。之外的代码,执行可以交叉
			for (int i = 0; i < 5; i++) {
				System.out.println(getName() + "..." + i);//getName()是定义在父类中的方法。
			}
		}
	}
}

输出如下
在这里插入图片描述
对lock的说明:
synchronized对象锁:该对象锁是Java中创建的一个对象,该对象可由任意类创建,只要求所创建的对象在多个线程之间共享即可。如果对象锁为全局成员,为了保证该对象在多个线程间共享,该成员往往被private static final修饰。

为什么通过synchronized就能实现多线程间串行运行呢?
被synchronized括着的部分就是线程执行临界区,每次仅能有一个线程执行该临界区中的代码:当多个线程中的某个线程先拿到对象锁, 则该线程执行临界区内的代码,其他线程只能在临界区外部等待,当此线程执行完临界区中的代码后,在临界区外部等待的其他线程开始再次竞争以获取对象锁,进而执行临界区中的代码,但只能有一条线程“胜利”。
临界区中的代码具有互斥性、唯一性和排它性:一个线程只有执行完临界区中的代码另一个线程才能执行。
2,

public class Text {
	public static void main(String[] args) {
		new CountThread1("线程1").start();
		new CountThread1("线程2").start();//记得就绪,调用start方法。默认情况下,线程之间交叉进行。
	}
}

class CountThread1 extends Thread{

	CountThread1(String n){
		super(n);
	}

	String name;//静态的,在对象之间共享,同一个数据。
	
	@Override
	public void run() {
		name=getName();//某一个线程对象改变名字之后,另一个线程直接拿来用。
		System.out.println(name+"~~~~~~~~~~");
		
		synchronized (String.class) {
			for (int i = 0; i < 5; i++) {
				System.out.println(name+ "..." + i);
			}
		}
	}
}

可能结果如下:
在这里插入图片描述
下边为该例子的变体

public class Text {
	public static void main(String[] args) {
		new CountThread1("线程1").start();
		new CountThread1("线程2").start();//记得就绪,调用start方法。默认情况下,线程之间交叉进行。
	}
}

class CountThread1 extends Thread{

	CountThread1(String n){
		super(n);
	}

	@Override
	public void run() {	//非静态的,线程对象调用。
		test();
	}
	
	void test() {
		synchronized (String.class) {//String.class是私有的构造方法,单例。数据共享,不交叉。
			for (int i = 0; i < 5; i++) {
				System.out.println(getName()+"..." + i);
			}
		}
	}
}

synchronized关键字

synchronized同步关键字有两种使用方式:
1,声明同步方法:

public synchronized void methodName( ){
	//同步操作方法体
}

例子:

public class Playground {

	public static void main(String[] args) {
		Bike bike = new Bike();
		PersonThread xiaoLin =new PersonThread("小林",bike);
		xiaoLin.start();
		PersonThread xiaoWang =new PersonThread("小王",bike);
		xiaoWang.start();
	}
}

class PersonThread extends Thread{

	Bike bike;
	String name;
	
	PersonThread(String name, Bike bike){
		super(name);
		this.name = name;
		this.bike = bike;
	}
	
	@Override
	public void run() {//run方法执行表示正在骑车
		bike.move(name);
	}
}

class Bike{
	public synchronized void move(String personName){	//若为非静态同步方法,则多线程间共享调用该方法的对象;若为静态同步方法,则多线程之间共享调用该方法的类;
		String threadName = Thread.currentThread().getName();
		System.out.println("当前线程:"+threadName);//判断当前哪条线程在执行该方法
		for (int i = 1; i <= 3; i++) {
			System.out.println(personName+":已经运行"+i+"秒");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

在这里插入图片描述
2,同步代码块

synchronized (需要同步操作的对象) {
	      //同步对象操作的语句
}

如下例子:

public class Playground {

	public static void main(String[] args) {
		PersonThread xiaoLin =new PersonThread("小林");
		xiaoLin.start();
		PersonThread xiaoWang =new PersonThread("小王");
		xiaoWang.start();
	}
}

class PersonThread extends Thread{

	String name;
	
	PersonThread(String name){
		this.name = name;
	}
	
	@Override
	public void run() {//run方法执行表示正在骑车
		Bike.move(name);
	}
}

class Bike{
	public static void move(String personName){
		String threadName = Thread.currentThread().getName();
		synchronized(Bike.class){
			System.out.println("当前线程:"+threadName);//判断当前哪条线程在执行该方法
			for (int i = 1; i <= 3; i++) {
				System.out.println(personName+":已经运行"+i+"秒");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

在这里插入图片描述

线程间协作

用以下例子说明线程间的协作

import java.util.Date;

public class Watch {

	String time;
	
	class DisplayThread extends Thread{//内部类:显示时间
		TimeThread timeThread;

		public DisplayThread(TimeThread timeThread) {
			this.timeThread=timeThread;
		}
		@Override
		public void run() {
			System.out.println(time);//直接显示时间,极大可能为null;
		}
	}
	
	class TimeThread extends Thread{//计算时间

		@Override
		public void run() {
			 time=new Date().toString();//创建时间对象
		}
	}
	
	public static void main(String[] args) {
		Watch watch=new Watch();
		
		TimeThread timeThread=watch.new TimeThread();//内部类创建对象方法。理想状态是先计算时间,再显示时间,线程之间的协作。
		timeThread.start();
		
		DisplayThread displayThread=watch.new DisplayThread(timeThread);
		displayThread.start();
	}
}

上述代码执行过程中,可能是显示器线程抢先于时间线程,所以会在没有得到时间的时候就输出,结果为null。
在这里插入图片描述
下面我们考虑实现总是可以显示时间
方法一:sleep()方法的使用

import java.util.Date;

public class Watch {

	String time;
	
	class DisplayThread extends Thread{//内部类
		TimeThread timeThread;

		public DisplayThread(TimeThread timeThread) {
			this.timeThread=timeThread;
		}
		@Override
		public void run() {
			if(time==null) {	//先来判断显示器线程此时要显示的时间是否为空
				try {
					sleep(100);//此时设置显示器线程阻塞一定的时间,理论上在阻塞期间应该是时间线程在执行,设置合理的阻塞时间,一定也会有时间显示。此法性能不高。
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(time);//直接显示时间,极大可能为null;
		}
	}
	
	class TimeThread extends Thread{

		@Override
		public void run() {
			 time=new Date().toString();//创建时间对象
		}
	}
	
	public static void main(String[] args) {
		Watch watch=new Watch();
		
		TimeThread timeThread=watch.new TimeThread();//内部类创建对象方法。理想状态是先计算时间,再显示时间,线程之间的协作。
		timeThread.start();
		
		DisplayThread displayThread=watch.new DisplayThread(timeThread);
		displayThread.start();
	}
}

一定会显示时间。
方法二:join()方法的使用

import java.util.Date;

public class Watch {

	String time;
	
	class DisplayThread extends Thread{//内部类
		TimeThread timeThread;

		public DisplayThread(TimeThread timeThread) {
			this.timeThread=timeThread;
		}
		@Override
		public void run() {
			if(time==null) {	//先来判断显示器线程此时要显示的时间是否为空
				try {//方法2:join
					timeThread.join();//执行join方法的显示器线程阻塞,一直到调用join方法的时间线程执行完毕。
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(time);
		}
	}
	
	class TimeThread extends Thread{

		@Override
		public void run() {
			 time=new Date().toString();//创建时间对象
		}
	}
	
	public static void main(String[] args) {
		Watch watch=new Watch();
		
		TimeThread timeThread=watch.new TimeThread();//内部类创建对象方法。理想状态是先计算时间,再显示时间,线程之间的协作。
		timeThread.start();
		
		DisplayThread displayThread=watch.new DisplayThread(timeThread);
		displayThread.start();
	}
}

一定有时间显示。
方法三:线程之间的协作——wait()方法与notify()方法的使用

import java.util.Date;

public class Watch {

	String time;
	String lock="";
	
	class DisplayThread extends Thread{//内部类
		TimeThread timeThread;

		public DisplayThread(TimeThread timeThread) {
			this.timeThread=timeThread;
		}
		@Override
		public void run() {
			synchronized (lock) {
				try {//方法3:线程协作
					lock.wait();//wait方法源自于object方法,执行该方法的线程会阻塞,1,共享对象调用wait方法,2,该方法必须用synchronized语句块,不然出异常,且锁定的对象
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(time);
		}
	}
	
	class TimeThread extends Thread{

		@Override
		public void run() {
			 time=new Date().toString();//创建时间对象
			 synchronized (lock) {//四个lock是同一个对象。
				lock.notify();
			}
		}
	}
	
	public static void main(String[] args) {
		Watch watch=new Watch();
		
		TimeThread timeThread=watch.new TimeThread();//内部类创建对象方法。理想状态是先计算时间,再显示时间,线程之间的协作。
		timeThread.start();
		
		DisplayThread displayThread=watch.new DisplayThread(timeThread);
		displayThread.start();
	}
}

说明:
synchronized关键字只是起到了多个线程“串行”执行临界区中代码的作用,但是哪个线程先执行,哪个线程后执行依无法确定,Object类中的wait()、notify()和notifyAll()三个方法解决了线程间的协作问题,通过这三个方法的“合理”使用可以确定多线程中线程的先后执行顺序:
wait():对象锁调用了wait()方法会使当前持有该对象锁的线程【也就是说该线程执行“对象锁.wait()”代码!】处于线程等待状态同时该线程释放对对象锁的控制权,直到在其他线程中该对象锁调用notify()方法或notifyAll()方法时等待此对象锁的线程才会被唤醒。
notify():对象锁调用notify()方法就会唤醒在此对象锁上等待的单个线程。
notifyAll():对象锁调用notifyAll()方法就会唤醒在此对象锁上等待的所有线程;调用notifyAll()方法并不会立即激活某个等待线程,它只能撤销等待线程的中断状态,这样它们就能够在当前线程退出同步方法或同步代码块法后与其它线程展开竞争,以争取获得资源对象来执行。
总之:谁调用了wait方法,谁就必须调用notify或notifyAll方法,并且“谁”是对象锁。
注意:
使用Object类中的wait()、notify()和notifyAll()三个方法需要注意以下几点:
1,wait()方法需要和notify()或notifyAll()方法中的一个配对使用,且wait方法与notify()或notifyAll()方法配对使用时不能在同一个线程中。
如下例子

public class Watch {

	public static void main(String[] args) {
		Object lockObj = new Object();
		new CounterThread(lockObj).start();
	}
}

class CounterThread extends Thread {

	private Object lockObj;

	public CounterThread(Object lockObj) {
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		synchronized (lockObj) {
			try {
				System.out.println("wait方法被执行!");
				lockObj.wait();//对此程序而言,下面代码永远不会被执行
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		synchronized (lockObj) {
			System.out.println("notify方法被执行!");
			lockObj.notify();
		}
	}
}

在上述代码中,notify方法永远不会被执行。
在这里插入图片描述
2,wait()方法、notify()方法和notifyAll()方法必须在同步方法或者同步代码块中使用,否则出现IllegalMonitorStateException 异常。

import java.util.Date;

public class Watch {

	String time;
	String lock="";	//此处对象可以是
	
	class DisplayThread extends Thread{//内部类
		TimeThread timeThread;

		public DisplayThread(TimeThread timeThread) {
			this.timeThread=timeThread;
		}
		@Override
		public void run() {
				try {//方法3:线程协作
					lock.wait();//wait方法源自于object方法,执行该方法的线程会阻塞,1,共享对象调用wait方法,2,该方法必须用synchronized语句块,不然出异常,且锁定的对象
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			System.out.println(time);
		}
	}

	class TimeThread extends Thread{
	
		@Override
		public void run() {
			 time=new Date().toString();//创建时间对象
				lock.notify();
		}
	}

	public static void main(String[] args) {
		Watch watch=new Watch();
		
		TimeThread timeThread=watch.new TimeThread();//内部类创建对象方法。理想状态是先计算时间,再显示时间,线程之间的协作。
		timeThread.start();
		
		DisplayThread displayThread=watch.new DisplayThread(timeThread);
		displayThread.start();
	}
}

在这里插入图片描述
3,调用wait()方法、notify()方法和notifyAll()方法的对象必须和同步锁对象是一个对象。,

import java.text.SimpleDateFormat;
import java.util.Date;

public class ElectronicWatch {
	
	String currentTime;
	DisplayThread displayThread = new DisplayThread();
	
	public static void main(String[] args) {
		new ElectronicWatch().displayThread.start();
	}

	/**
	 * 该线程负责显示时间
	 */
	class DisplayThread extends Thread{
		
		@Override
		public synchronized void run() {
			new TimeThread().start();
			try {
				this.wait();//this指代当前对象,为DisplayThread对象。
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(currentTime);
		}
	}

	/**
	 * 该线程负责获取时间
	 */
	class TimeThread extends Thread{
		
		@Override
		public synchronized void run() {
			try {
				sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			String pattern = "yyyy-MM-dd HH:mm:ss";
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			currentTime = sdf.format(new Date());
			this.notify();////this指代当前对象,为TimeThread对象。
		}
	}
}

this不是同一个对象,上述代码不执行
在这里插入图片描述

sleep()方法和wait()方法区别

1,sleep()方法被调用后当前线程进入阻塞状态,但是当前线程仍然持有对象锁,在当前线程sleep期间,其它线程无法执行sleep方法所在临界区中的代码。

public class ElectronicWatch {

	public static void main(String[] args) {
		Object lockObj = new Object();
		new PrintThread("1号打印机",lockObj).start();
		new PrintThread("2号打印机",lockObj).start();
	}
}

class PrintThread extends Thread {
	
	private Object lockObj;

	public PrintThread(String threadName, Object lockObj) {
		super(threadName);
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		synchronized (lockObj) {//当某台打印机执行临界区中的代码,输出线程名后由于调用了sleep方法,从而使得该打印机线程阻塞30秒,在这30秒期间因该打印机线程仍然持有对象锁,从而导致另一台打印机线程只能在30秒后才能执行临界区中的代码。
			System.out.println(getName());
			try {
				sleep(30000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

输出:控制台先输出一号打印机,隔三十秒之后再输出二号打印机。
2,对象锁调用了wait()方法会使当前持有该对象锁的线程处于线程等待状态同时该线程释放对对象锁的控制权,在当前线程处于线程等待期间,其它线程可以执行wait方法所在临界区中的代码。

public class ElectronicWatch {

	public static void main(String[] args) {
		Object lockObj = new Object();
		new PrintThread("1号打印机",lockObj).start();
		new PrintThread("2号打印机",lockObj).start();
	}
}

class PrintThread extends Thread {
	
	private Object lockObj;

	public PrintThread(String threadName, Object lockObj) {
		super(threadName);
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		synchronized (lockObj) {
			System.out.println(getName());
			try {
				lockObj.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

代码分析:
当某台打印机执行临界区中的代码,输出线程名后由于对象锁调用了wait方法,从而使得该打印机线程进入阻塞状态,该打印机线程同时释放对对象锁的拥有权,从而导致另一台打印机线程可以在前一台打印机线程阻塞期间即能执行临界区中的代码,当对象锁再次调用wait方法后另一台打印机线程也会进入阻塞状态。
在这里插入图片描述

wait方法

例1:

public class ElectronicWatch {

	public static void main(String[] args) {
		Object lockObj = new Object();
		new CounterThread("1号计数器",lockObj).start();
		new CounterThread("2号计数器",lockObj).start();
	}
}

class CounterThread extends Thread {

	private Object lockObj;

	public CounterThread(String threadName, Object lockObj) {
		super(threadName);
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		int i = 1;
		while (true) {
			synchronized (lockObj) {
				System.out.println(getName() + ":" + i);
				try {
					lockObj.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				i++;
			}
		}
	}
}

代码分析:
尽管此处是死循环,但由于对象锁lockObj调用了wait()方法,使得分别持有该lockObj对象锁的“1号计数器”线程和“2号计数器”线程处于线程等待状态,所以循环并没有继续下去。
在这里插入图片描述
例2:

import java.text.*;
import java.util.Date;

public class ElectronicWatch {

	public static void main(String[] args) {
		TimeThread1 timeThread = new TimeThread1 ();
		timeThread.start();

		synchronized (timeThread) {
			try {
				timeThread.wait();//为什么时间线程没有进入阻塞状态呢?——timeThread变量所代表的《对象【充当】对象锁》,由于该代码在main方法中,也就是说将来由主线程执行临界区中的代码,也就是说《主线程是持有对象锁的线程》,主线程执行完“timeThread.wait()”代码后进入阻塞状态,是主线程进入阻塞状态而非时间线程,这也是main方法中“System.out.println("main方法");”代码不执行的原因。
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("main方法");//为什么这行代码不执行?——由于主线程进入了阻塞状态,所以该行代码不执行
	}
}

class TimeThread1 extends Thread{

	@Override
	public void run() {
		DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
		while (true) {
			String currentTime = dateFormat.format(new Date());
			System.out.println(currentTime);
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

notifyAll方法

class CounterThread extends Thread {

	private Object lockObj;

	public CounterThread(String threadName, Object lockObj) {
		super(threadName);
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		int i = 1;
		while (true) {
			synchronized (lockObj) {
				System.out.println(getName() + ":" + i);
				try {
					lockObj.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				i++;
			}
		}
	}
}

class NotifyAllThread extends Thread {

	private Object lockObj;

	public NotifyAllThread(Object lockObj) {
		this.lockObj = lockObj;
	}

	@Override
	public void run() {
		synchronized (lockObj) {
			System.out.println("notifyAll方法执行完毕");
			lockObj.notifyAll();
		}
	}
}

public class Test {

	public static void main(String[] args) {
		Object lockObj = new Object();
		new CounterThread("1号计数器", lockObj).start();
		new CounterThread("2号计数器", lockObj).start();
		
		try {
			Thread.sleep(5000);//主线程阻塞
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		new NotifyAllThread(lockObj).start();
	}
}

在这里插入图片描述
代码分析:
尽管此处是死循环, “1号计数器”线程和“2号计数器”线程输出1后对象锁lockObj调用了wait()方法,使得两个线程进入线程等待状态;但主线程在sleep 5000毫秒后启动了NotifyAllThread线程类创建的线程对象,该线程对象在执行run方法时对象锁调用了notifyAll方法,致使两个线程全部被唤醒,所以两个线程又循环了一遍。

JFM7VX690T型SRAM型现场可编程门阵列技术手册主要介绍的是上海复旦微电子集团股份有限公司(简称复旦微电子)生产的高性能FPGA产品JFM7VX690T。该产品属于JFM7系列,具有现场可编程特性,集成了功能强大且可以灵活配置组合的可编程资源,适用于实现多种功能,如输入输出接口、通用数字逻辑、存储器、数字信号处理和时钟管理等。JFM7VX690T型FPGA适用于复杂、高速的数字逻辑电路,广泛应用于通讯、信息处理、工业控制、数据中心、仪表测量、医疗仪器、人工智能、自动驾驶等领域。 产品特点包括: 1. 可配置逻辑资源(CLB),使用LUT6结构。 2. 包含CLB模块,可用于实现常规数字逻辑和分布式RAM。 3. 含有I/O、BlockRAM、DSP、MMCM、GTH等可编程模块。 4. 提供不同的封装规格和工作温度范围的产品,便于满足不同的使用环境。 JFM7VX690T产品系列中,有多种型号可供选择。例如: - JFM7VX690T80采用FCBGA1927封装,尺寸为45x45mm,使用锡银焊球,工作温度范围为-40°C到+100°C。 - JFM7VX690T80-AS同样采用FCBGA1927封装,但工作温度范围更广,为-55°C到+125°C,同样使用锡银焊球。 - JFM7VX690T80-N采用FCBGA1927封装和铅锡焊球,工作温度范围JFM7VX690T80-AS相同。 - JFM7VX690T36的封装规格为FCBGA1761,尺寸为42.5x42.5mm,使用锡银焊球,工作温度范围为-40°C到+100°C。 - JFM7VX690T36-AS使用锡银焊球,工作温度范围为-55°C到+125°C。 - JFM7VX690T36-N使用铅锡焊球,工作温度范围JFM7VX690T36-AS相同。 技术手册中还包含了一系列详细的技术参数,包括极限参数、推荐工作条件、电特性参数、ESD等级、MSL等级、重量等。在产品参数章节中,还特别强调了封装类型,包括外形图和尺寸、引出端定义等。引出端定义是指对FPGA芯片上的各个引脚的功能和接线规则进行说明,这对于FPGA的正确应用和电路设计至关重要。 应用指南章节涉及了FPGA在不同应用场景下的推荐使用方法。其中差异说明部分可能涉及产品之间的性能差异;关键性能对比可能包括功耗速度对比、上电浪涌电流测试情况说明、GTH Channel Loss性能差异说明、GTH电源性能差异说明等。此外,手册可能还提供了其他推荐应用方案,例如不使用的BANK接法推荐、CCLK信号PCB布线推荐、JTAG级联PCB布线推荐、系统工作的复位方案推荐等,这些内容对于提高系统性能和稳定性有着重要作用。 焊接及注意事项章节则针对产品的焊接过程提供了指导,强调焊接过程中的注意事项,以确保产品在组装过程中的稳定性和可靠性。手册还明确指出,未经复旦微电子的许可,不得翻印或者复制全部或部分本资料的内容,且不承担采购方选择使用本文描述的产品和服务的责任。 上海复旦微电子集团股份有限公司拥有相关的商标和知识产权。该公司在中国发布的技术手册,版权为上海复旦微电子集团股份有限公司所有,未经许可不得进行复制或传播。 技术手册提供了上海复旦微电子集团股份有限公司销售及服务网点的信息,方便用户在需要时能够联系到相应的服务机构,获取最新信息和必要的支持。同时,用户可以访问复旦微电子的官方网站(***以获取更多产品信息和公司动态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值