实验目的:学习使用thread类创建线程,以及怎样处理线程同步问题,2,实验内容

多线程创建 运行 和终止的过程。并叙述处理多线程同步中的问题的几种方法
08-11-29 &
多线程机制 博奕树   线程是操作系统的一种新概念,是比传统进程粒度更小的可并发执行的单位。C和C++采用单线程体系结构,而Java却提供了多线程支持。一方面,Java环境本身就是多线程的;另一方面,Java语言内置多线程控制,提供了1个类Thread,由它负责启动、运行和终止线程,并可检查线程状态。Java的线程还包括了用于对多线程实行并发控制的同步原语。利用Java的多线程编程接口,可方便地构筑支持多线程的应用,提高程序的并发度和执行效率。  笔者曾参与开发了基于IBM Visual Age for Java环境的黑白棋博奕程序。通过将Java多线程机制引入博奕树搜索,明显加大了搜索平均深度,取得了很好的效果。 1 线程的概念及生命周期   所谓“线程”是“进程”中某个单一顺序的控制流。新兴的操作系统,如Macos、Windows NT等,均把线程视为其基本执行单位。线程也是Java中相当重要的组成部分,如任何1个Java Applet的Paint()和update()方法均由AWT绘图与事件处理线程所调用。图1表示了线程在它的生命周期中的任何时刻所能处的状态以及引起状态改变的方法。
图1 线程生命周期 2 博奕   博奕就是对策或斗智,它不仅存在于棋类游戏中,而且存在于政治、经济、军事和生物竞争之中。在人工智能领域,大多以下棋为例来研究博奕规律。博奕为人工智能提供了1个很好的试验场所,人工智能中的许多概念和方法都是从棋类程序中提炼而得,博奕的许多研究成果现已用于军事指挥和经济决策系统之中。  博奕问题的状态空间——博奕树是1种特殊的与/或树,结点代表格局。所谓格局就是反映下棋态势的全部信息,如棋子位置、轮到谁走下一步等,可用状态变量表示。图2是1棵博奕树的局部。
图2 博奕树局部   在2人零和非偶然性全信息博奕中(即对奕双方利益完全对立),对奕双方都力图在状态空间中找到1条使自己得分最多的路径。设所有使甲方获胜的终局为可解端结点,得分为+b;所有使乙方获胜的终局为不可解端结点,得分为-b;分别按甲方与乙方走法,从端结点向根可一步步推算出各中间结点和根结点的得分,这就是对博奕树的极小极大化分析法。  然而,即使1个很小的博奕状态空间,也可能生成十分庞大的博奕树,它可能有的终局数也很大。企图对它们采用完整的极小极大化分析是不可能的,实际可行的办法是:在1个被分析的结点下面,只生成“似合理的”博奕树的一部分(给定深度限制,除去重复和希望不大的分枝),并用得分函数f对树的各叶结点进行得分估值,然后用极大极小化分析计算树中各结点及根结点的得分估值,以便选择当前估计的最佳策略。这些计算所得的估值称为倒推估值(Back up Value),其精度有赖于得分函数。  显然,如何在限定的时间内(本系统为5s)尽量提高搜索的深度是至关重要的。一般认为这有待硬件设施的提升,然而研究后发现,在传统的单线程博奕程序中,对手用于思考棋步的时间对己方而言是闲置的,而且也很难被利用。但在引入多线程机制后,采用“时间窃取”的技术,将对方的思考时间转变为我方的可利用时间,用于增加搜索深度,或在搜索深度不变条件下,提高得分函数的精度,从而显著改善了博奕程序的整体性能。 3 应用实例   基于上述思想,我们在IBM Visual Age for Java环境下开发了黑白棋博奕程序。下面给出该程序的主体架构及涉及多线程应用的相关代码。为便于理解有必要先将黑白棋规则作一下简要介绍。  1.黑白棋规则  (1)棋盘为8×8方格,双方分别执黑白2色棋子。  (2)初始状态:棋盘中间4格放入黑、白各2棋子,如图3(a)。  (3)投子、吃子规则(以黑子为例):  ①当黑棋落子时,以此格为中心分别沿8个方向(上、下、左、右、左上、右上、左下、右下)来寻找原有的黑白子,若在某个方向上找到的第一个黑子与刚投下的黑子间无空格,则这2个黑子间的所有白子变为黑子,如图3(b)、图3(c)。
图3 黑白棋规则   ②黑子若找不到使白棋变为黑色的走法,则必须放弃一步,由对方走棋;若找得到,则不能放弃该步。  ③胜负判定,当双方均放弃一步或棋盘上放满棋子时,清点棋盘上的两色棋子,多者获胜。  2.程序设计要求  (1)由计算机和玩家各执一色棋子,在棋盘中放棋。玩家可选择先手或后手。  (2)程序走每一步棋的计算时间限制为5s(Pentium 75,32MB RAM),超时则由程序强制落子。  3.程序设计  (1)本软件是1个Applet,程序中定义实现了4个类:  Reversi:是整个Applet的骨架,负责用户界面的管理;  RevBoard:负责与棋局相关的各程序成分,如搜索器、棋局存储等程序的调度;  RevSearch:搜索器;  RevPlate:定义了棋局的内部存储结构及1组维护方法。  (2)本软件运行过程中,将有2个线程th-search,th-sleep并行执行,如图4所示(假定玩家先手)。
图4 th-search 和 th-sleep 的运行状态   当Applet开始运行时,启动th-search线程,开始搜索;当玩家落子后,即启动th-sleep线程,并立刻执行sleep(5000),进行睡眠状态。th-search执行搜索。5s后,th-sleep醒来,要求th-search提供搜索结果,并由相关程序据此落子,而th-sleep则转为suspend状态,此时玩家在思考,而th-search的搜索也在进行。当对方落子后,又重新启动th-sleep线程,如此周而复始,直到程序结束。可以看出th-sleep实际上起到了1个计时器的作用。  (3)程序代码  public class Reversi extends Applet R  {   //界构造部分程序略  }  public class RevBoard extends Panel  {   RevP//棋局   RevS//搜索器   public RevBoard();   plate=new RevPlate();   Plate,Init();//创建棋局并初始化   searcher=new RevSearch();   search.Search(plate)//启动搜索线程   Thread th-  public boolean mouseDown(Event evt,int x,int y)  {   //玩家落子时所做处理   if(plate.valid(x,y)//如果落子位置有效   //落子记录,重画棋盘   //Searcher针对落子情况作相应调整   if(th-sleep==null)//若th-sleep未创建   {    th-sleep=new Thread(this);    th-sleep.start();   }   else   th-sleep resume();  }  Public void run()//th-sleep线程的主要执行部分  {   while(true)   {    try{     Thread sleep(5000);    }catch(Exception e);    getAnswer();//取搜索结果    th-sleep suspend();   }  }}Class RevSearch implements Runnalbe{  RevB  Thread th-//搜索线程  void search(RevPlate plate)  {   if(th-search==null)//若th-search尚未创建   {    th-search=new Thread(this);    th-search.start();   }  }   Public Void run()//th-search 的实际执行部分   {   }  }  class RevPlate  {//略} 4 结束语   由于引入了多线程技术,本软件取得了很好的效果。在IBM Pentium 75、32MB内存机器上,利用α—β剪枝方法构造博奕树,结果5s内平均搜索深度达4层,访问状态结点达7000个,与没采用多线程技术的程序相比,效率提高了1.5~2倍。实践证明,Java多线程机制具有很高的实用价值。事实上,由于多线程的核心思想即并行,因此,在基于多处理机的系统上,多线程机制的威力必将得到更大程度的发挥。此外,Java多线程技术的应用也不仅仅局限于上述的博奕领域,如何将Java多线程技术广泛应用到分布式系统中,是需要深入探讨的问题。
请登录后再发表评论!您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
24李后浪实验五 多线程.doc 6页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:150 &&
24李后浪实验五 多线程
你可能关注的文档:
··········
··········
实验五多线程实验课程名:Java程序设计专业班级:12网工2班学号:姓名:李后浪实验时间:实验地点:K4-307指导教师:冯珊一、实验目的和要求①掌握使用Thread的子类创建线程;②学习使用Thread类创建线程;③学习处理线程同步问题。?
二、实验内容?任务1汉字打字练习。实验要求:编写一个Java应用程序,在主线程中再创建一个Frame类型的窗口,在该窗口中再创建1个线程giveWord。线程giveWord每隔2秒钟给出一个汉字,用户使用一种汉字输入法将该汉字输入到文本框中。源代码:WordThread.javaimportjava.awt.*;publicclassWordThreadextendsThread{intk=19968;LWordThread(Labelcom){=}publicvoidrun(){k=19968;while(true){word=(char)k;com.setText(&&+word);try{Thread.sleep(6000);//调用sleep方法使得线程中断6000豪秒}catch(InterruptedExceptione){}k++;if(k&=29968)k=19968;}}}ThreadFrame.javaimportjava.awt.*;importjava.awt.event.*;publicclassThreadFrameextendsFrameimplementsActionListener{LabelwordLBTextFieldinputText,scoreTWordThreadgiveW//用WordThread声明一个giveWord对象intscore=0;ThreadFrame(){wordLabel=newLabel(&&,Label.CENTER);wordLabel.setFont(newFont(&&,Font.BOLD,72));button=newButton(&开始&);inputText=newTextField(3);scoreText=newTextField(5);scoreText.setEditable(false);giveWord=newWordThread(wordLabel);//创建giveWord,将wordLabel传递给WordThread构造方法的参数button.addActionListener(this);inputText.addActionListener(this);add(button,BorderLayout.NORTH);add(wordLabel,BorderLayout.CENTER);PanelsouthP=newPanel();southP.add(newLabel(&输入标签所显示的汉字后回车:&));southP.add(inputText);southP.add(scoreText);add(southP,BorderLayout.SOUTH);setBounds(100,100,350,180);setVisible(true);validate();addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});}publicvoidactionPerformed(ActionEvente){if(e.getSource()==button){if(!(giveWord.isAlive()))//giveWord调用方法isAlive(){giveWord=newWordThread(wordLabel);}try{giveWord.start();//giveWord调用方法start()}catch(Exceptionexe){}}elseif(e.getSource()==inputText){if(inputText.getText().equals(wordLabel.getText())){score+=1000;}scoreText.setText(&得分:&+score);inputText.setText(null);}}}ThreadWordMainClass.javapublicclassThreadWordMainClass{publicstaticvoi
正在加载中,请稍后...JavaSE学习52:细说多线程之Thread类和Runable接口
一线程创建的两种方式比较
线程创建和启动有两种方式,这里只是列出步骤,不再进行详细解释。
(1)继承Thread类
class MyThread extends Thread{
public void run(){
MyThread mt=new MyThread();//创建线程
mt.start();//启动线程
(2)实现Runnable接口
class MyThread implements Runnable{
public void run(){
MyThread mt=new MyThread();
Thread td=new Thread(mt);//创建线程
td.start();//启动线程
(3)两种方式的比较
1)Runnable方式可以避免Thread方式由于单继承特性带来的缺陷。
2)Runnable方式的代码可以被多个线程(Thread实例)共享,适合于多个线程处理同一资源的情况。
二模拟应用场景
模拟一个火车站买票的场景,某车次还剩下5张火车票,有三个窗口去卖这5张火车票,我们使用三个线程模拟三个窗口同时卖这5张火车票,我们看Thread方式和Runnable方式这两种方式模拟出一个什么样的结果。
(1)使用Thread方式模拟买票
TicketsThread.java源文件代码:
class MyThread extends Thread{
//一共有五张火车票
private int ticketsCount = 5;
//窗口,也就是线程的名字
//构造方法
public MyThread(String name){
this.name =
public void run(){
while(ticketsCount & 0){
//如果还有票,就卖掉一张
ticketsCount--;
System.out.println(name+&卖了1张票,剩余票数为:&+ticketsCount);
public class TicketsThread{
public static void main(String[] args){
//创建三个线程,模拟三个窗口买票
MyThread mt1 = new MyThread(&窗口1&);
MyThread mt2 = new MyThread(&窗口2&);
MyThread mt3 = new MyThread(&窗口3&);
//启动三个线程,也就是窗口开始卖票
mt1.start();
mt2.start();
mt3.start();
运行结果:
得到的结果并不是我们想要的结果。
在票的数量加static修饰关键字得到的结果是正确的。这里不再进行演示。
(2)使用Runnable方式模拟买票
TicketsRunnable.java源文件代码:
class MyThread1 implements Runnable{
//一共有五张火车票
private int ticketsCount = 5;
public void run(){
while(ticketsCount & 0){
//如果还有票,就卖掉一张
ticketsCount--;
System.out.println(Thread.currentThread().getName()+&卖了1张票,剩余票数为:&+ticketsCount);
public class TicketsRunnable{
public static void main(String[] args){
MyThread1 mt = new MyThread1();
//创建三个线程,模拟三个窗口买票
Thread th1 = new Thread(mt,&窗口1&);
Thread th2 = new Thread(mt,&窗口2&);
Thread th3 = new Thread(mt,&窗口3&);
//启动三个线程,也就是窗口开始卖票
th1.start();
th2.start();
th3.start();
得到了预期的结果:
(3)结果分析
由于线程的执行是随机的,打印的结果也是随机的。
Thread方式
三个线程,创建了三个Thread对象,每个线程都有自己的Thread对象,都有自己的ticketsCount变量,它们三个线程并不是共享ticketsCount变量,也就是每个线程都可以卖出5张火车票,即三个窗口卖出去15张火车票。
Runnable方式
三个线程共用一个Runnable对象,也就是三个线程共用一个ticketsCount变量,即三个窗口一共卖了5张火车票。前者不是一个线程三个对象,是三个Thread对象,也是三个线程,这三个线程启动后都会执行5次卖票,实现不了共享&5张票&这个资源,所以输出就会有15张票卖出去,显然不符合实际,用Runnable就可以解决这个问题,创建的三个线程可以共享&5张票&这个资源。
ticketsCont变量是实例变量,它的值自然是存在堆中(每个java对象在堆中都会占据一定内存,而实例变量的值就是存储在这块内存中,类似于结构体,因此每个对象对应一个ticketsCont的值),ticketsCont跟值传递没有关系啊,如果是Runnable方式的话,传递的也只是MyThread对象引用的副本,不管ticketsCont的事,但是因为ticketsCont的值在引用和引用副本所指向的堆内存中,所以无论是引用还是引用副本改变了堆内存中ticketsCont的值,都会产生效果!
这个根据你的需要来操作,这样说吧,如果有一个比较大的资源要你下载,那么你用Thread方式那么你就只能一个线程去吧这个资源下载完,如果是runable方式的话你就可以多new几个子线程来出来,通过共享runable对象里面的资源来用多个子线程来下载这个资源,这样的话,下载资源的时候 runable方法会使下载的线程多一些几率在cpu里面,也会让你下载速度变快继承Thread类是多个线程分别完成自己的任务,实现Runnable接口是多个线程共同完成一个任务。
三线程的生命周期
线程的生命周期转换示意图:
线程的生命周期:
1)创建:新建一个线程对象,如Thread thd=new Thread()。
2)就绪:创建了线程对象后,调用了线程的start()方法(注意:此时线程只是进入了线程队列,等待获取CPU服
务,具备了运行的条件,但并不一定已经开始运行了)。
3)运行:处于就绪状态的线程,一旦获取了CPU资源,便进入到运行状态,开始执行run()方法里面的逻辑。
4)阻塞:一个正在执行的线程在某些情况下,由于某种原因而暂时让出了CPU资源,暂停了自己的执行,便进入
了阻塞状态,如调用了sleep()方法。
5)终止:线程的run()方法执行完毕,或者线程调用了stop()方法,线程便进入终止状态。
这里我们可以用一个经典的线问题就是生产者和消费者问题的实例:
import java.util.*;
public class ProducerConsumer{
public static void main(String[] args){
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
new Thread(c).start();
//生产与消费对象
class WoTou{
//构造方法
WoTou(int id){
//重写toString()方法
public String toString(){
return &WoTou : & +
class SyncStack{
int index = 0;
WoTou[] arrWT = new WoTou[4];
public synchronized void push(WoTou wt){
while(index == arrWT.length){
//这里的wait()方法指的是Object类中的方法
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
//这里的notifyAll()方法指的是唤醒所有线程,而notify()方法唤醒一个线程
this.notifyAll();
arrWT[index] =
public synchronized WoTou pop(){
while(index == 0){
//这里的wait()方法指的是Object类中的方法
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
//这里的notifyAll()方法指的是唤醒所有线程,而notify()方法唤醒一个线程
this.notifyAll();
return arrWT[index];
class Producer implements Runnable{
SyncStack ss =
Producer(SyncStack ss){
public void run(){
for(int i=0; i&20; i++){
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println(&生产了:& + wt);
Thread.sleep((int)(Math.random() * 200));
}catch(InterruptedException e){
e.printStackTrace();
class Consumer implements Runnable{
SyncStack ss =
Consumer(SyncStack ss){
public void run(){
for(int i=0; i&20; i++){
WoTou wt = ss.pop();
System.out.println(&消费了: & + wt);
Thread.sleep((int)(Math.random() * 1000));
}catch(InterruptedException e){
e.printStackTrace();
运行结果:
关于一些问题的解析:
执行线程sleep()方法是依然占着cpu的,操作认为该当前线程正在运行,不会让出系统资源。
执行wait()方法是让线程到等待池等待,让出一系列的系统资源,其他线程可以根据调度占用cpu线程的资源有不少,但应该包含CPU资源和锁资源这两类。
sleep(long mills):让出CPU资源,但是不会释放锁资源。
wait():让出CPU资源和锁资源。
锁是用来线程同步的,sleep(long mills)虽然让出了CPU,但是不会让出锁,其他线程可以利用CPU时间片了,但如果其他线程要获取sleep(long mills)拥有的锁才能执行,则会因为无法获取锁而不能执行,继续等待。但是那些没有和sleep(long mills)竞争锁的线程,一旦得到CPU时间片即可运行了。
四守护线程
(1)守护线程理论知识
Java线程分为两类:
1)用户线程:运行在前台,执行具体的任务。程序的主线程、连接网络的子线程等都是用户线程。
2)守护线程:运行在后台,为其他前台线程服务。守护线程的特点是一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作。守护线程的应用:连接池中的检测线程和JVM启动后的检测线程等等。最常见的守护线程:垃圾回收线程
设置守护线程:
可以通过调用Thread类的setDaemon(true)方法来设置当前的线程为守护线程。
使用守护线程的注意事项:
1)setDaemon(true)必须在start()方法之前调用,否则会抛出IllegalThreadStateException异常。
2)在守护线程中产生的新线程也是守护线程。
3)不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑。
(2)守护线程代码示例:
import java.io.*;
import java.util.*;
class DaemonThread implements Runnable{
public void run(){
System.out.println(&进入守护线程&+Thread.currentThread().getName());
writeToFile();
}catch(Exception e){
e.printStackTrace();
System.out.println(&退出守护线程&);
private void writeToFile() throws Exception{
File filename = new File(&E:\\Java\\JavaSE\\Thread&+File.separator+&daemon.txt&);
OutputStream os = new FileOutputStream(filename,true);
int count = 0;
while(count & 999){
os.write((&\r\nword&+count).getBytes());
System.out.println(&守护线程&+Thread.currentThread().getName()+&向文件中写入了word&+ count++);
Thread.sleep(1000);
public class DaemonThreadDemo{
public static void main(String[] args){
System.out.println(&进入主线程&+Thread.currentThread().getName());
DaemonThread daemonThread = new DaemonThread();
Thread thread =new Thread(daemonThread);
thread.setDaemon(true);
thread.start();
Scanner sc = new Scanner(System.in);
sc.next();
System.out.println(&退出主线程&+Thread.currentThread().getName());
运行结果:
(3)使用jstack生成线程快照
作用:生成JVM当前时刻线程的快照(threaddump,即当前进程中所有线程的信息)。
目的:帮助定位程序问题出现的原因,如长时间停顿、CPU占用率高等。
jstack命令行工具
你安装JDK安装目录下的bin文件夹下:
位置:E:\Java\develop\jdk1.8.0_25\bin
如何使用jstack
在cmd中输入:jstack
我们去任务管理器中找到一个进程的PID:
生成快照:
(1)怎样解决死锁的问题
1)尽量避免不必要的synchronized关键字。
2)可以用其他方法替换synchronized关键字,比如标志不可变量。
3)保证synchronized代码块简练。
(2)创建线程的建议
根据两种创建线程方法的比较,得出的结论是使用实现Runnable接口的方法创建的多线程更好一些,另外,就是需要重点注意,程序中的同一个资源指的是同一个Runnable对象。建议多使用Runnable这种方式创建多线程。
1)程序中的同一资源指的是同一个Runnable对象。
2)安全的卖票程序中需要加入同步(Synchronized)。我们的代码过程中并没有加入,如果需要完善,就必须加入同步锁。2016年计算机二级Java用Thread类创建线程考点
为帮助将要参加计算机等级考试的朋友更好的学习,本站编辑特别为大家整理了Java用Thread类创建线程考点的内容,请大家认真学习。
用Thread类创建线程
在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。Thread类的构造方法被重载了八次,构造方法如下:
1.public Thread( );
2.public Thread(Runnable target);
3.public Thread(String name);
4.public Thread(Runnable target, String name);
5.public Thread(ThreadGroup group, Runnable target);
6.public Thread(ThreadGroup group, String name);
7.public Thread(ThreadGroup group, Runnable target, String name);
8.public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
Runnable target
实现了Runnable接口的类的实例。要注意的是Thread类也实现了Runnable接口,因此,从Thread类继承的类的实例也可以作为target传入这个构造方法。
String name
线程的名子。这个名子可以在建立Thread实例后通过Thread类的setName方法设置。如果不设置线程的名子,线程就使用默认的线程名:Thread-N,N是线程建立的顺序,是一个不重复的正整数。
ThreadGroup group
当前建立的线程所属的线程组。如果不指定线程组,所有的线程都被加到一个默认的线程组中。关于线程组的细节将在后面的章节详细讨论。
long stackSize
线程栈的大小,这个值一般是CPU页面的整数倍。如x86的页面大小是4KB.在x86平台下,默认的线程栈大小是12KB。
一个普通的Java类只要从Thread类继承,就可以成为一个线程类。并可通过Thread类的start方法来执行线程代码。虽然Thread类的子类可以直接实例化,但在子类中必须要覆盖Thread类的run方法才能真正运行线程的代码。下面的代码给出了一个使用Thread类建立线程的例子
11. public class Thread1 extends Thread
13. public void run()
15. System.out.println(this.getName());
17. public static void main(String[] args)
19. System.out.println(Thread.currentThread()。getName());
20. Thread1 thread1 = new Thread1();
21. Thread1 thread2 = new Thread1 ();
22. thread1.start();
23. thread2.start();
上面的代码建立了两个线程:thread1和thread2.上述代码中的005至008行是Thread1类的run方法。当在014和015行调用start方法时,系统会自动调用run方法。在007行使用this.getName()输出了当前线程的名字,由于在建立线程时并未指定线程名,因此,所输出的线程名是系统的默认值,也就是Thread-n的形式。在011行输出了主线程的线程名。标签:
计算机等级考试当前热搜
试题最新更新君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

 

随机推荐