线程同步的方法_C++线程同步的方法
2025-03-26 06:59 - 立有生活网
Ja多线程同步设计中使用Metux[3]
semaphore叫做”信号量”,信号量的初始值,可以用来控制线程并发访问的数量,信号量的初始值为1,代表同时只允许1条线程访问资源,保证线程同步为什么要在acquire()和attempt( 方法的开始都要检查当前线程的中断标志呢?这是为了在当前线程已经被打断时 可以立即返回 而不会仍然在锁标志上等待 调用一个线程的interrupt()方法根据当前线程所处的状态 可能产生两种不同的结果 当线程在运行过程中被打断 则设置当前线程的中断标志为true;如果当前线程阻塞于wait() sleep() join() 则当前线程的中断标志被清空 同时抛出InterruptedException 所以在上面代码的位置( )也捕获了InterruptedException 然后再次抛出InterruptedException
线程同步的方法_C++线程同步的方法
线程同步的方法_C++线程同步的方法
代码是手写的,省略了一些简单的东西,请自行补全。
release()方法简单地重置inuse_标志 并通知其它线程
attempt()方法是利用Ja的Object wait(long)进行计时的 由于Object wait(long)不是一个的时钟 所以attempt(long)方法也是一个粗略的计时 注意代码中位置( ) 在超时时返回
Mutex是Sync的一个基本实现 除了实现了Sync接口中的方法外 并没有添加新的方法 所以 Mutex的使用和Sync的完全一样 在concurrent包的API中Doug给出了一个精细锁定的List的实现示例 我们这儿也给出 作为对Mutex和Sync使用的一个例子
class Node{Object ; Node next;Mutex lock = new Mutex();// 每一个都持有一个锁Node(Object x Node n){ = x;next = n;}}class List{protected Node head;// 指向列表的头// 使用Ja的synchronized保护head域// (我们当然可以使用Mutex 但是这儿似乎没有这样做的必要protected synchronized Node getHead(){ return head; }boolean search(Object x) throws InterruptedException{Node p = getHead();if (p == null) return false;// (这儿可以更加紧凑 但是为了演示的清楚 各种情况都分别进行处理)p lock acquire();// Prime loop by acquiring first lock // (If the acquire fails due to// interrupt the mod will throw// InterruptedException now // so there is no need for any// further cleanup )for (;;){if (x equals(p )){p lock release();// 释放当前的锁return true;}else{Node nextp = p next;if (nextp == null){p lock release();// 释放持有的锁return false;}else{try{nextp lock acquire();// 在释放当前锁之前获取下一个的锁}catch (InterruptedException ex){p lock release();// 如果获取失败 也释放当前的锁 throw ex;}p lock release();// 释放上个的锁 现在已经持有新的锁了p = nextp;}}}}synchronized void add(Object x){// 使用synchronized保护head域head = new Node(x head);}// other similar trersal and update mods }
lishixinzhi/Article/program/Ja/gj/201311/27681
Ja多线程锁如何进行数据同步共享
当线程退出同步方法调用时,该线程会释放monitor,这将允许其他等待的线程获得monitor以使对同步方法的调用执行下去。就像下面这样://遍历代执行的线程Ja多线程锁是为了解决数据同步中的数据安全问题 下面我们就来详细的学习下有关于Ja多线程锁的相关问题 只有不断的学习才能不断的提高自身的相关技术
大多数应用程序要求线程互相通信来同步它们的动作 在Ja程序中最简单实现同步的方法就是上Ja多线程锁 为了防止同时访问共享资源 线程在使用资源的前后可以给该资源上锁和开锁 想给复印机上锁 任一时刻只有一个职员拥有钥匙 若没有钥匙就不能使用复印机
给共享变量上Ja多线程锁就使得Ja线程能够快速方便地通信和同步 某个线程若给一个对象上了锁 就可以知道没有其他线程能够访问该对象 即使在抢占式模型中 其他线程也不能够访问此对象 直到上锁的线程被唤醒 完成工作并开锁 那些试图访问一个上锁对象的线程通常会进入睡眠状态 直到上锁的线程开锁 一旦锁被打开 这些睡眠进程就会被唤醒并移到准备就绪队列中
在Ja编程中 所有的对象都有锁 线程可以使用synchronized关键字来获得锁 在任一时刻对于给定的类的实例 方法或同步的代码块只能被一个线程执行 这是因为代码在执行之前要求获得对象的Ja多线程锁 继续我们关于复印机的比喻 为了避免复印冲突 我们可以简单地对复印资源实行同步 如同下列的代码例子 任一时刻只允许一位职员使用复印资源 通过使用方法(在 Copier 对象中)来修改复印机状态 这个方法就是同步方法 只有一个线程能够执行一个Copier对象中同步代码 因此那些需要使用Copier对象的职员就必须排队等候
class CopyMachine {
public synchronized void makeCopies(Document d int nCopies) {
//only one thread executes this at a time
}
public void loadPaper() {
//multiple threads could access this at once!
synchronized(this) {
//only one thread accesses this at a time
//feel free to use shared resources overwrite members etc
Fine grain Ja多线程锁
在对象级使用锁通常是一种比较粗糙的方法 为什么要将整个对象都上锁 而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源 就不需要只为了让一个线程使用其中一部分资源 就将所有线程都锁在外面 由于每个对象都有Ja多线程锁 可以如下所示使用虚拟对象来上锁
class FineGrainLock {
Object xlock = new Object() ylock = new Object();
public void foo() {
synchronized(xlock) {
//access x here
}
//do soming here but don t use shared resources
synchronized(ylock) {
//access y here
}
}
public void bar() {
synchronized(this) {
//access both x and y here
}
//do soming here but don t use shared resources
}
}
lishixinzhi/Article/program/Ja/gj/201311/27267
ja的同步方法和非同步方法,下面程序怎么解释?
2、互斥量这道题的关键在于弄清}楚关键字 synchronized的作用:
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一段时间只能有一个线程得到执行,而另一个线程只有等当前线程执行完以后才能执行这块代码。
synchronized关键可以修饰函数、函数内语句。无论它加上方法还是对象上,它取得的锁都是对象,而不是把一段代码或是函数当作锁。
如题: printClass 方法被synchronized修饰以后,线程一执行该方法的时候,线程二只能等待线程一执行完才能执行,控制台打印 AAAAABBBBB
printClass 的synchronized关键字去掉以后,线程一和线程二都可以执行该方法,所以控制台打印ABABABABAB,
A和B的两个线程的执行顺序是由先后的 ,一般的,谁先声明谁先执行,上题线程A先声明所以线程A先执行。所以不管加不加synchronized都先打印A。但是不是的!.start 方法只是把线程放到执行队列里,真正执行还是需要看CPU,如果对线程执行顺序感兴趣的话可以去了解一下join 方法。
iOS线程同步(各种锁)
待执行的线程,注意这里必须是Runnable接口类型,下面会解释在iOS开发中经常会遇到一块资源被多个线程共享的情况,也就是多个线程会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件,当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题
试试我改过的这个使用线程同步技术(同步就是协同步调,按预定的先后顺序进行),常见的同步技术时加锁
os_unfair_lock用于取代不安全的OSSpinLock ,从iOS10开始才支持,从底层调用看,等待os_unfair_lock锁的线程会处于休眠状态,并非忙等,使用需要导入头文件#import
mutex叫做”互斥锁”,等待锁的线程会处于休眠状态,使用需要导入头文件#import
NSLock、NSRecursiveLock是对mutex普通锁的封装,NSLock遵守NSLocking协议
初始化锁 NSLock lock = [[NSLock alloc] init];
NSRecursiveLock也是对mutex递归锁的封装,API跟NSLock基本一致
NSCondition是对mutex和cond的封装,NSCondition遵守NSLocking协议
NSCondition通常用于生产者消费者模式的业务中,当不满足条件时调用wait方法让消费者线程等待,当条件满足时调用signal方法通知消费者线程。
NSConditionLock是对NSCondition的进一步封装,可以设置具体的条件值
NSConditionLock都可以设置不同线程间的依赖,让满足条件值的线程先执行,不满足条件的线程处于等待状态。
@synchronized是对mutex递归锁的封装,源码查看:objc4中的 objc-sync.mm 文件,@synchronized(obj)内部会生成obj对应的递归锁,然后进行加锁、解锁作
性能从高到底排序
dispatch_barrier_async
dispatch_barrier_async又叫栅栏函数,这个函数传入的并发队列必须是自己通过dispatch_queue_cretate创建的,如果传入的是一个串行或是一个全局的并发队列,那这个函数便等同于dispatch_async函数的效果,使用栅栏函数可以保证同一时间只有一个线程可进行写作,读作可以有多少个线程进行。
请问linux下C编程多线程同步和异步的区别,如何能实现程序的同步和异步编程
@param runnable同步和异步的区别:
{taskList.Add(worker.Put());1、同步就是说多个任务之间是有先后关系的,一个任务需要等待另一个任务执行完毕才能继续执行。
2、异步就是说多个任务之间没有先后关系,不需要相互等待各做各的事。
同步编程方法:
1、信号量
异步无需考虑资源冲突,不需特别处理。
同步和异步的区别:
1、同步就是说多个任务之间是有先后关系的,一个任务需要等待另一个任务执行完毕才能继续执行。
2、异步就是说多个任务之间没有先后关系,不需要相互等待各做各的事。
同步编程方法:
1、信号量
异步无需考虑资源冲突,不需特别处理。
你问这样的问题,只有拷贝大段大段的文字
同步和异步这些知识应该在作系统的消费者和生产者/哲学家进餐里找,要自己去看的,多说无益
如何能实现程序的同步和异步编程,这个要看实现的需求,和编码的能力了
需要进一步的观察才行,细心一点会好的!
Ja多线程初学者指南(10):使用Synchronized关键字同步类方法
public static synchronized Singleton getInstance() { }要想解决 数据 的问题 最简单的方法就是使用synchronized关键字来使run方法同步 代码如下
public synchronized void run(){ }
从上面的代码可以看出 只要在void和public之间加上synchronized关键字 就可以使run方法同步 也就是说 对于同一个Ja类的对象实例 run方法同时只能被一个线程调用 并当前的run执行完后 才能被其他的线程调用 即使当前线程执行到了run方法中的yield方法 也只是暂停了一下 由于其他线程无法执行run方法 因此 最终还是会由当前的线程来继续执行 先看看下面的代码
sychronized关键字只和一个对象实例绑定
class Test { public synchronized void mod() { } } public class Sync implements Runnable { private Test test; public void run() { thod(); } public Sync(Test test) { this test = test; } public static void main(String[] args) throws Exception { Test test = new Test(); Test test = new Test(); Sync sync = new Sync(test ); Sync sync = new Sync(test ); new Thread(sync ) start(); new Thread(sync ) start(); } }
在Test类中的mod方法是同步的 但上面的代码建立了两个Test类的实例 因此 test 和test 的mod方法是分别执行的 要想让mod同步 必须在建立Sync类的实例时向它的构造方法中传入同一个Test类的实例 如下面的代码所示
Sync sync = new Sync(test );
不仅可以使用synchronized来同步非静态方法 也可以使用synchronized来同步静态方法 如可以按如下方式来定义mod方法
class Test { public static synchronized void mod() { }}
建立Test类的对象实例如下
Test test = new Test();
对于静态方法来说 只要加上了synchronized关键字 这个方法就是同步的 无论是使用thod() 还是使用thod()来调用mod方法 mod都是同步的 并不存在非静态方法的多个实例的问题
在 种设计模式中的单件(Singleton)模式如果按传统的方法设计 也是线程不安全的 下面的代码是一个线程不安全的单件模式
package test;// 线程安全的Singleton模式class Singleton{ private static Singleton sample; private Singleton() { } public static Singleton getInstance() { if (sample == null) { Thread yield(); // 为了放大Singleton模式的线程不安全性 sample = new Singleton(); } return sample; }}public class MyThread extends Thread{ public void run() { Singleton singleton = Singleton getInstance(); System out println(singleton hashCode()); } public static void main(String[] args) { Thread threads[] = new Thread[ ]; for (int i = ; i < threads length; i++) threads[i] = new MyThread(); for (int i = ; i < threads length; i++) threads[i] start(); }}
在上面的代码调用yield方法是为了使单件模式的线程不安全性表现出来 如果将这行去掉 上面的实现仍然是线程不安全的 只是出现的可能性小得多
程序的运行结果如下
上面的运行结果可能在不同的运行环境上有所有同 但一般这五行输出不会完全相同 从这个输出结果可以看出 通过getInstance方法得到的对象实例是五个 而不是我们期望的一个 这是因为当一个线程执行了Thread yield()后 就将CPU资源交给了另外一个线程 由于在线程之间切换时并未执行到创建Singleton对象实例的语句 因此 这几个线程都通过了if判断 所以 就会产生了建立五个对象实例的情况(可能创建的是四个或三个对象实例 这取决于有多少个线程在创建Singleton对象之前通过了if判断 每次运行时可能结果会不一样)
要想使上面的单件模式变成线程安全的 只要为getInstance加上synchronized关键字即可 代码如下
当然 还有更简单的方法 就是在定义Singleton变量时就建立Singleton对象 代码如下
private static final Singleton sample = new Singleton();
然后在getInstance方法中直接将sample返回即可 这种方式虽然简单 但不知在getInstance方法中创建Singleton对象灵活 读者可以根据具体的需求选择使用不同的方法来实现单件模式
在使用synchronized关键字时有以下四点需要注意
syn关注中,期待高手来解答.chronized关键字不能继承
虽然可以使用synchronized来定义方法 但synchronized并不属于方法定义的一部分 因此 synchronized关键字不能被继承 如果在父类中的某个方法使用了synchronized关键字 而在子类中覆盖了这个方法 在子类中的这个方法默认情况下并不是同步的 而必须显式地在子类的这个方法中加上synchronized关键字才可以 当然 还可以在子类方法中调用父类中相应的方法 这样虽然子类中的方法不是同步的 但子类调用了父类的同步方法 因此 子类的方法也就相当于同步了 这两种方式的例子代码如下
在子类方法中加上synchronized关键字
class Parent{ public synchronized void mod() { }}class Child extends Parent{ public synchronized void mod() { }}
在子类方法中调用父类的同步方法
class Parent{ public synchronized void mod() { }}class Child extends Parent{ public void mod() { thod(); }}
在定义接口方法时不能使用synchronized关键字
构造方法不能使用synchronized关键字 但可以使用下节要讨论的synchronized块来进行同步
synchronized可以自由放置
在前面的例子中使用都是将synchronized关键字放在方法的返回类型前面 但这并不是synchronized可放置位置 在非静态方法中 synchronized还可以放在方法定义的最前面 在静态方法中 synchronized可以放在static的前面 代码如下
public synchronized void mod();synchronized public void mod();public static synchronized void mod();public synchronized static void mod();synchronized public static void mod();
但要注意 synchronized不能放在方法返回类型的后面 如下面的代码是错误的
public void synchronized mod();public static void synchronized mod();
synchronized关键字只能用来同步方法 不能用来同步类变量 如下面的代码也是错误的
public synchronized int n = ;public static synchronized int n = ;
虽然使用synchronized关键字同步方法是最安全的同步方式 但大量使用synchronized关键字会造成不必要的资源消耗以及性能损失 虽然从表面上看synchronized锁定的是一个方法 但实际上synchronized锁定的是一个类 也就是说 如果在非静态方法mod 和mod 定义时都使用了synchronized 在mod 未执行完之前 mod 是不能执行的 静态方法和非静态方法的情况类似 但静态和非静态方法不会互相影响 看看如下的代码
package test;public class MyThread extends Thread{ public String modName; public static void mod(String s) { System out println(s); while (true) ; } public synchronized void mod () { mod( 非静态的mod 方法 ); } public synchronized void mod () { mod( 非静态的mod 方法 ); } public static synchronized void mod () { mod( 静态的mod 方法 ); } public static synchronized void mod () { mod( 静态的mod 方法 ); } public void run() { try { getClass() getMod(modName) invoke(this); } catch (Exception e) { } } public static void main(String[] args) throws Exception { MyThread myThread = new MyThread (); for (int i = ; i <= ; i++) { thodName = mod + String valueOf(i); new Thread(myThread ) start(); sleep( ); } }}
运行结果如下
非静态的mod 方法静态的mod 方法
lishixinzhi/Article/program/Ja/gj/201311/27526
ja类内多个函数如何同步
wait();步是让线程同步,第二部是让线程有顺序。
同步:我们可以用synchronized来解决。
ja线程同步原理: ja会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized mods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占有权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。
public void test() {
synchronized{taskList.Add(worker.GetAndProcess()); (this) {
//做一些事
}}
顺序:我们可以用List来解决,因为它是有序的。我们只需要将要执行的线程放入到List中不就好解决了吗
上代码:
让多个线程同步顺序执行的线程管理器
@author bianrx
@date 2012.1.18
SynchronizedRunMultiThread
/
public class SyncMar {
/
private List
public SyncMar(){}
public SyncMar(List
this.runnableList = runnableList;
}public void setRunnable(List
this.runnableList = runnableList;
}public void run() {
for(Runnable runnable: runnableList) {
runThread(runnable);
}}
按顺序同步执行多个线程
@author bianrx
@date 2012.1.18
/
private void runThread(Runnable runnable) {
synchronized (this) {
runnable.run();//这里需要注意的是:必须调用run方法,因为如果你调用了start方法,线程只会向JVM请求资源,但是未必就执行其中的run。
//这个方法是同步的,所以当前只有一个线程占用了this对象。
}}
}测试代码:有两个要执行的线程
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("运行线程1");
}}
public class Thread2 extends Thread {
@Override
public void run() {
System.out.println("运行线程2");
}}
//主函数测试
public class MainTest {
@param args
@throws ParseException
@throws InterruptedException
/
public static void main(String[] args) throws ParseException, InterruptedException {
List
runnableList.add(new Thread1());
runnableList.add(new Thread2());
while(true) {
Thread.sleep(1000);
new SyncMar(runnableList).run();
System.out.println("---------------");
除非你还有一个工具类 来控制调用类X中的A B方法,那么同步就要加在这个工具类中了
如果是A方法中调用B 那么就在调用B的地方 加一个同步代码块 Synchronized(this){调用B } 可以保证每次只有一个线程访问 调用B 处的代码
用 sychronized 修饰方法
线程同步关键字?
OSSpinLock叫做”自旋锁”,等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源,目前已经不再安全,从iOS10已经废弃了,可能会出现优先级反转问题,如果等待锁的线程优先级较高,它会一直占用着CPU资源,优先级低的线程就无法释放锁,使用需要导入头文件#importsynchronized 关键字。简单叙述下用法:synchronized 代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
//叫所有工人一起送零件到各自的目的厂房(并行)求实现c#多线程数据同步读写代码或思路
这里我们不扯设计模式的问题,先来从现实角度想象一下这个场景。
定原本厂里的工人是这样干活的:他只知道“从某厂房A(输入)拿一个零件,加工完毕后送入另一厂房B(输出)。我们只需要告诉他“开始干活(调用了BeginWork方法)”然后他就会开始循环的干活直到你告诉他停下来(EndWork)。当然了,他只用遵守的一条规矩:A厂房里有零件他就拿出来加工,没有零件自然就是等着了。
你可以注意到这个工人自身只关心几件事物:厂房source,厂房target,(被命令)开始循环工作,(被命令)结束工作。换做程序语言,他的实现大体是这样的:
public class SimpleWorker
{public SimpleWorker(Factory source,Factory target){...}
public async Task BeginWork(){while(...){...}}
public async Task EndWork(){...}
}(注意两个异步方法。不使用同步方法的原因是活儿是工人干的,老板只是叫他“开始工作”和“停止工作”而已。实际上在生产-消费设计模式中也并不建议由主线程或调度线程自己开子线程来运行各个工作线程。)
不久后我们有了新的工作要求,就是让工人们同步的进行某项作。想象一下我们有一个工长,他负责管理手下的几个工人,要求他们取零件加工时一起做,当大家都完成后,工长会命令大家一起把加工好的零件放到各自的输出厂房去,完成后再次叫大家一起取零件加工,如此往复。
那么如何站在编程的角度实现呢?
首先我们注意到工人关注的事情变成了:厂房A,厂房B,工长叫他取零件加工,工长叫他送加工后的零件到目的厂房。这中间还涉及一个事儿,因为加工完零件并不一定会立刻送到目的厂房,所以工人还需要找地方把刚加工好的零件存起来。其次,我们多了一个工长,他将负责统一调度所有工人干活,当然了,对于当老板的我们来说,工长只需要接受老板的“开始工作”和“停止工作”命令。
于是我们有了这样的工人:
public class Worker
{private Product processedProduct;
public Worker(Factory source,Factory target){...}
public async Task GetAndProcess(){...}
public async Task Put(){...}
}请注意工人加工零件的方法和送零件的方法被我们从原来的BeginWork中抽取了出来以方便工长做调度。
下来是我们的工长:
public class WorkerMar
{private ICollection
priv//这里只会有一个线程来调用该方法,因为只有一个this对象作为资源分配给该线程ate bool requiredToStop;
private TaskCompletionSource
{myWorkers=workers;
}public async Task BeginWork()
{await Task.Factory.StartNew(()=>
{var taskList=new List
while(!requiredToStop)
{//叫所有工人一起取零件加工(并行)
foreach(var worker in myWorkers)
}//等到所有工人都完成
await Task.WhenAll(taskList.ToArray());
taskList.Clear();
foreach(var worker in myWorkers)
}//等到所有工人都完成
await Task.WhenAll(taskList.ToArray());
taskList.Clear();
}allWorksDone.SetResult(true);
});
}public async Task EndWork()
{//不再执行下一轮任务
requiredToStop=true;
//一直等到所有当前任务执行完毕
await allWorksDone.Task;
}}
如此一来,作为boss,我们只需要:
var boxA=new Factory();
var boxB=new Factory();
//... 放点东西在两个仓库
var worker1=new Worker(boxA,boxB);
var worker2=new Worker(boxB,boxA);
var workerMar=new WorkerMar(npublic WorkerMar(ICollection
workerMar.BeginWork();
await workerMar.EndWork();
,关于“停止工作”请注意一点,为了方便举例,我特意将所有的BeginWork和EndWork方法都写成了异步。这两个方法的异步返回时间都是在while循环跳出后,功能上有所重叠。实际上我们只需要其中任意一个方法为异步即可满足所有需求。
有疑问请追问。
ja (线程的同步与并发)
/class Mystack
如果是A B 是两个单独的方法,没有任何关联 那么基本上是没法实现的..{int index=0;
private char[]date=new char [10];
public void push(char c)
{synchronized(this)
{if(index<10)
{date[index]=c;
index++;
if(index==10)
notify();
}else
{try
{System.out.println ("push wait");
}catch(Exception e)
{e.printStackTrace();
System.err.println(e);
}}
}}
public void pop()
{synchronized(this)
{if(index!=0)
{if(index>9)
System.out.print ("B:pop");
System.out.println (date[index]);
if(index==0)
notify();
}else
{try
{System.out.println ("pop wait");
}catch(Exception e)
{e.printStackTrace();
System.err.println (e);
}}
}}
}class PushChar extends Thread
{Mystack s;
char c;
PushChar(Mystack s)
{this.s=s;
}public void run()
{System.out.println ("start push");
for (int i=0; i<20; i++)
{c=(char)(Math.random()26+'A');
s.push(c);
System.out.println("A:push "+c);
}}
}class PopChar extends Thread
{Mystack s;
char c;
PopChar(Mystack s)
{this.s=s;
}public void run()
{System.out.println ("start pop");
for(int j=0;j<20;j++)
s.pop();
}}
public class Test
{public static void main (String[] args)
{Mystack s=new Mystack();
PushChar a=new PushChar(s);
PopChar b=new PopChar(s);
a.start();
b.start();
}}
基因工程教学设计方案 基因工程及其应用教学

基因工程教学设计方案 基因工程及其应用教学设计 基因工程教学设计方案 基因工程及其应用教学设计 今天怡怡来给大家分享一些关于基因工程及其应用教学设计方面的知识吧,希望大家会喜欢哦···
包含交字的成语 包含交字的成语有哪些

交字的四字成语 1. 交给的交的四字词语 交的四字词语 : 包含交字的成语 包含交字的成语有哪些 包含交字的成语 包含交字的成语有哪些 饥寒交迫、 星月交辉、 交相辉映、 君子之交、 悲喜交集···
蝴蝶型是不是不好进 站立前屈能进入吗

蝴蝶型房子怎么样 方位是否正确,方位不准分析全错 蝴蝶型是不是不好进 站立前屈能进入吗 蝴蝶型是不是不好进 站立前屈能进入吗 一定要有准确的方位,这个涉及到起盘 不是大概东北,也要看···