文档库 最新最全的文档下载
当前位置:文档库 › cahpter9多线程

cahpter9多线程

cahpter9多线程
cahpter9多线程

8.2 Java多线程机制

●多线程是为一个程序开辟多条执行路线,让一个程序按照多条不同的执行路线共同工作。通过多线程可以方便地开发出能够处理多个任务的应用程序。

●多线程的程序能更好地表述和解决现实世界的具体问题,是计算机应用开发和程序设计的一个必然发展趋势。Java语言的重要特点是支持多线程。

●多线程编程展示1 源程序Clock.java 多线程编程展示2 源程序ThreeThread.java

8.2.1 基本概念

1.程序、进程与线程

●程序是一段静态代码,它是应用程序执行的蓝本。进程是程序的一次动态执行过程,它对应从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程。程序是静态的,它就是一段代码。进程是动态的,同一程序每次的执行过程可能不同。

●线程是比进程更小的执行单位,是进程内的顺序控制流。一个进程中可以包含多个线程,每个线程对应程序的一条执行路线,多个线程构成同一程序的多条执行路线。线程是动态的。进程中的每个线程都有产生、存在和消亡的过程。进程由操作系统管理,线程由进程控制。

●每个进程拥有一段专用的内存区域。一个进程内的多个线程可以共享内存单元,利用这些共享单元实现数据交换、通信与必要的同步操作。

2.线程的生命周期与状态

●默认情况下,每个Java程序都只有一个执行路线,即只有一个线程,称该线程为主线程。对于Application程序,主线程是main()方法的执行路线。对于Applet程序,主线程是让浏览器加载并执行Java小程序。

●要为程序开辟多条执行路线,即实现多线程,必须创建新线程。Thread类以及子类用于创建线程对象,每个线程对象对应一个线程,是程序的一条执行路线。

●每个线程都有一个从诞生到消亡的生命周期。线程在生命周期中通常要经历五种状态,分别是新建状态、就绪状态、运行状态、阻塞状态和消亡状态。

(1)新建状态

新建状态是线程的第一个状态。新建线程对象处于新建状态。

例如:Thread myThread=new Thread();

(2)就绪状态

●状态也称可运行状态。启动新建状态的线程使它进入就绪状态。

●Java通过start()方法启动线程。

例如:myThread.start();

●就绪状态的线程已经具备运行条件,它进入就绪队列排队,等待运行。

(3)运行状态

●当就绪状态的线程被选中并开始运行,则进入运行状态。在Java中,执行run()方法进入运行状态。

●Thread类及其子类都定义了空的run()方法。要实现线程的操作和功能,需要重载run()方法,即在run()方法中编写具体语句。

(4)阻塞状态

●阻塞状态也称挂起状态。一个正在执行的线程在某些情况下会暂时中止运行,从运行状态变成阻塞状态。以下操作都会使线程进入阻塞状态。

①调用sleep()方法使线程进入睡眠状态。

②调用suspend()方法使线程进入挂起状态。

③为等待一个条件变量,调用wait()方法。

④执行费时的输入或输出操作。

●只有消除引起阻塞的原因,处于阻塞状态的线程才可以转入就绪状态,重新进到就绪队列中排队,以便从中止处继续运行。

(5)消亡

处于消亡状态的线程不具有继续运行的能力。线程消亡的原因有两个。

●一是线程完成它的全部工作,正常结束运行,即执行完run()方法中的每条语句后退出。

●二是线程被提前强制终止,如执行stop()方法或destroy()终止线程。

8.2.2 实现多线程

●用Java程序实现多线程有两种途径:

一种是创建线程类Thread的子类,一种是定义类实现Runnable接口。

●无论哪种途径,都要使用Thread类及其方法,都要在线程的run()方法中编写实现线程具体操作的语句。

1.Thread类

创建线程需要使用线程类Thread。Thread类综合了一个线程拥有的属性和方法。

(1)Thread类的构造方法

①public Thread():创建一个线程对象。

②public Thread(String threadName):创建一个线程对象,并为它指定一个字符串名称供以后使用。

③public Thread(Runnable target):创建一个线程对象,并为它指定一个实现Runnable接口的对象。

④public Thread(Runnable target,String threadName):创建一个线程对象,并为它指定实现Runnable接口的对象和字符串名称。

利用构造方法创建新线程对象之后,该对象的有关数据被初始化,并进入线程生命周期的第一个状态(新建状态)。

(2)与线程运行和线程状态有关的方法

①public void start():用于启动线程对象。线程对象被启动后,由新建状态转入就绪状态,并进入就绪队列排队,等待运行。

②public void run():用于定义线程执行的操作。Thread类和Runnable接口都包括空的run()方法,两者的作用相同。要赋予线程具体功能,就要实现run()方法。

③public void sleep(long millisencond):用于使正在执行的线程暂时睡眠,睡眠时间由参数millisencond决定。millisecond以毫秒为单位。

线程的调度执行按照线程优先级进行。当优先级高的线程未完成时,优先级低的线程没有机会获得处理器。如果优先级高的线程需要完成一些费时的操作,或者需要优先级低的线程做一些配合工作,那么优先级高的线程应该让出处理器资源,睡眠一段时间,使优先级低的线程有机会执行。

为实现这一目的,可调用sleep()方法。

④public boolean isAlive():用于判断线程是否存活。

⑤public void stop():用于终止线程。

(3)与线程优先级有关的常量和方法

每个线程都有一个优先级。Java为线程规定1至10十种优先级。Thread类提供表示线程优先级的静态常量和与优先级有关的方法。

①Thread.MAX_PRIORITY:代表最高优先级,通常为10。

②Thread.MIN_PRIORITY:代表最小优先级,通常为1。

③Thread.NORM_PRIORITY:代表普通优先级,缺省数值为5。

④public void setPriority(int priority):设置线程的优先级。

⑤public int getPriority():获取线程的优先级。

(4)其他方法

①public String getName():获得线程的字符串名称。

②public void setName(String name):为线程对象设置字符串名称。

③public int activeCount():获得当前存活的线程个数。

④public Thread currentThread():获得当前正在运行的线程对象。

2.实现多线程

每个Java程序默认只有一个线程(主线程)。定义新线程是实现多线程的基本工作。

(1)通过Thread类的子类实现多线程

主要涉及以下工作:

①定义一个Thread类的子类,用该子类表示用户线程类。

②在用户线程类中重写run()方法,使run()方法包含用户线程的操作。

③建立用户线程类对象。

④调用start()方法启动线程,以便执行run()方法。

(2)通过Runnable接口实现多线程

主要涉及以下工作:

①定义类实现Runnable接口,用该类表示用户线程类。

②在用户线程类中重写run()方法。

③建立用户线程类对象。

④调用start()方法启动线程。

例通过Runnable接口实现多线程。

显示时间

程序如下:

import java.awt.*;

import java.applet.*;

import java.util.*;

public class displayTime extends Applet implements Runnable

{Thread clockThread;

Font f=new Font("宋体",Font.BOLD,20);

public void start()

{ setFont(f);

if (clockThread==null)

{ clockThread=new Thread(this,"Clock");

clockThread.start();

}

}

public void run() //实现Runnable接口中空的run()方法

{ while(clockThread!=null)

{ repaint();

try{ clockThread.sleep(1000);}

catch(InterruptedException e){ return; }

}

}

public void paint(Graphics g)

{ Date now=new Date(); //创建时间类对象

g.drawString(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds(),20,30);

}

public void stop()

{clockThread.stop();

clockThread=null;

}

}

16.JAVA网络编程实验 多线程

Java网络编程实验报告 (实验六) 学号:姓名: 实验项目名称:多线程教师评分: 一、实验目的 (1)了解线程的概念。 (2)学习简单的多线程编程。 二、预习内容及要求(要求写出预习内容) 1.进程和线程的概念 进程是程序一次动态执行的过程,对应从代码加载、执行到执行结束这样一个完整的过程,也是进程自身从产生、发展到消亡的过程。 线程是比进程更小的执行单元,一个进程在执行过程中,可以产生多个线程。每个线程都有自身的产生、执行和消亡的过程。 2.线程的状态与生命周期 ●新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此 时它已经有了相应的内存空间和其他资源。 ●运行:线程创建之后就具备了运行的条件,一旦轮到它来享用CPU资源时,即JVM将CPU 使用权切换给该线程时,此线程的就可以脱离创建它的主线程独立开始自己的生命周期了(即 run方法执行的过程)。 ●中断:有4种原因的中断,CPU资源从当前线程切换给其他线程、执行了sleep(int millsecond) 方法、执行了wait()方法、进入阻塞状态。 ●死亡:run方法结束。 3.线程的创建 在Java语言中,与线程支持密切相关的是https://www.wendangku.net/doc/5a6948925.html,ng.Thread类和https://www.wendangku.net/doc/5a6948925.html,ng.Runnable接口。Runnable 接口定义很简单,只有一个run方法。任何一个类如果希望自己的实例能够以线程的形式执行,都可以来实现Runnable接口。 继承Thread类和实现Runnable接口,都可以用来创建Thread对象,效果上并没有什么不同。继承Thread类的方法很明显的缺点就是这个类不能再继承其他的类了,而实现Runnable接口不会有这个麻烦。 另外,在继承Thread类的代码中,this其实就是指当前正在运行的线程对象,如果使用实现Runnable 接口的方式,要得到当前正在执行的线程,需要使用Thread.currentThread()方法。 线程创建后仅仅是占有了内存资源,在JVM管理的线程中还没有这个线程,此线程必须调用start ()方法(从父类继承的方法)通知JVM,这样JVM就会知道又有一个新一个线程排队等候切换了。

进程管理实验报告

进程的控制 1 .实验目的 通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。 【答:进程概念和程序概念最大的不同之处在于: (1)进程是动态的,而程序是静态的。 (2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。 (3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。 (4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。】2 .实验内容 (1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。 (2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。 (3) 编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new

program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。 3 .实验步骤 (1)gedit创建进程1.c (2)使用gcc 1.c -o 1编译并./1运行程序1.c #include #include #include #include void mian(){ int id; if(fork()==0) {printf(“child id is %d\n”,getpid()); } else if(fork()==0) {printf(“child2 id %d\n”,getpid()); } else {id=wait(); printf(“parent id is %d\n”,getpid()); }

解决多线程中11个常见问题

并发危险 解决多线程代码中的11 个常见的问题 Joe Duffy 本文将介绍以下内容:?基本并发概念 ?并发问题和抑制措施 ?实现安全性的模式?横切概念本文使用了以下技术: 多线程、.NET Framework 目录 数据争用 忘记同步 粒度错误 读写撕裂 无锁定重新排序 重新进入 死锁 锁保护 戳记 两步舞曲 优先级反转 实现安全性的模式 不变性 纯度 隔离 并发现象无处不在。服务器端程序长久以来都必须负责处理基本并发编程模型,而随着多核处理器的日益普及,客户端程序也将需要执行一些任务。随着并发操作的不断增加,有关确保安全的问题也浮现出来。也就是说,在面对大量逻辑并发操作和不断变化的物理硬件并行性程度时,程序必须继续保持同样级别的稳定性和可靠性。 与对应的顺序代码相比,正确设计的并发代码还必须遵循一些额外的规则。对内存的读写以及对共享资源的访问必须使用同步机制进行管制,以防发生冲突。另外,通常有必要对线程进行协调以协同完成某项工作。 这些附加要求所产生的直接结果是,可以从根本上确保线程始终保持一致并且保证其顺利向前推进。同步和协调对时间的依赖性很强,这就导致了它们具有不确定性,难于进行预测和测试。 这些属性之所以让人觉得有些困难,只是因为人们的思路还未转变过来。没有可供学习的专门API,也没有可进行复制和粘贴的代码段。实际上的确有一组基础概念需要您学习和适应。很可能随着时间的推移某些语言和库会隐藏一些概念,但如果您现在就开始执行并发操作,则不会遇到这种情况。本

文将介绍需要注意的一些较为常见的挑战,并针对您在软件中如何运用它们给出一些建议。 首先我将讨论在并发程序中经常会出错的一类问题。我把它们称为“安全隐患”,因为它们很容易发现并且后果通常比较严重。这些危险会导致您的程序因崩溃或内存问题而中断。 当从多个线程并发访问数据时会发生数据争用(或竞争条件)。特别是,在一个或多个线程写入一段数据的同时,如果有一个或多个线程也在读取这段数据,则会发生这种情况。之所以会出现这种问题,是因为Windows 程序(如C++ 和Microsoft .NET Framework 之类的程序)基本上都基于共享内存概念,进程中的所有线程均可访问驻留在同一虚拟地址空间中的数据。静态变量和堆分配可用于共享。请考虑下面这个典型的例子: static class Counter { internal static int s_curr = 0; internal static int GetNext() { return s_curr++; } } Counter 的目标可能是想为GetNext 的每个调用分发一个新的唯一数字。但是,如果程序中的两个线程同时调用GetNext,则这两个线程可能被赋予相同的数字。原因是s_curr++ 编译包括三个独立的步骤: 1.将当前值从共享的s_curr 变量读入处理器寄存器。 2.递增该寄存器。 3.将寄存器值重新写入共享s_curr 变量。 按照这种顺序执行的两个线程可能会在本地从s_curr 读取了相同的值(比如42)并将其递增到某个值(比如43),然后发布相同的结果值。这样一来,GetNext 将为这两个线程返回相同的数字,导致算法中断。虽然简单语句s_curr++ 看似不可分割,但实际却并非如此。 忘记同步 这是最简单的一种数据争用情况:同步被完全遗忘。这种争用很少有良性的情况,也就是说虽然它们是正确的,但大部分都是因为这种正确性的根基存在问题。 这种问题通常不是很明显。例如,某个对象可能是某个大型复杂对象图表的一部分,而该图表恰好可使用静态变量访问,或在创建新线程或将工作排入线程池时通过将某个对象作为闭包的一部分进行传递可变为共享图表。 当对象(图表)从私有变为共享时,一定要多加注意。这称为发布,在后面的隔离上下文中会对此加以讨论。反之称为私有化,即对象(图表)再次从共享变为私有。 对这种问题的解决方案是添加正确的同步。在计数器示例中,我可以使用简单的联锁: static class Counter { internal static volatile int s_curr = 0; internal static int GetNext() { return Interlocked.Increment(ref s_curr);

java多线程实验报告

java多线程实验报告 篇一:西北农林科技大学java多线程实验报告 实验7 多线程 1.实验目的 (1) 掌握Java多线程的概念和实现方法 (2) 掌握Java多线程的同步问题 2.实验内容 任务一:火车售票 假设有火车票1000张,创建10个线程模拟10个售票点,每个售票点100毫秒买一张票。打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。程序运行结果见左图。 打开Eclipse Tickets.java public class Ticket extends Thread { int ticket =1000; String name =""; public void run(){ while(true){synchronized(name){ if(ticket "第" + Thread.currentThread().getName()+ "售票点卖出了第" + ticket-- + "张票"); } } } }} try{ } catch(InterruptedException e){ }

Thread.sleep(100); Test.java public class Test { } public static void main(String args[]){} Ticket t = new Ticket(); new Thread(t,"1").start(); new Thread(t,"2").start(); new Thread(t,"3").start(); new Thread(t,"4").start(); new Thread(t,"5").start(); new Thread(t,"6").start(); new Thread(t,"7").start(); new Thread(t,"8").start(); new Thread(t,"9").start(); new Thread(t,"10").start(); 任务二:银行存款 假设某家银行,它可接受顾客的汇款,每做一次汇款,便可计算出汇款的总额。现有两个顾客,每人都分3次,每次100元将钱到入。试编写一个程序,模拟实际作业。 程序如下: classCBank { private static int sum=0; public static void add(int n){ inttmp=sum; tmp=tmp+n;// 累加汇款总额 try{ Thread.sleep((int)(10000*Math.random())); //

8-实验八Java多线程操作(实验报告内容)

实验八 Java多线程操作 (实验报告) 一、目的 1.掌握Java多线程操作。 二、实验内容 启动线程,线程休眠,线程同步,等待和唤醒 三、实验环境 JDK1.6+dos环境 四、实验原理 通过案例掌握多线程操作。 五、实验步骤 1、设计一个线程操作类,要求可以产生三个线程对象,并可以分 别设置三个线程的休眠时间,如下所示: 线程A,休眠10秒 线程B,休眠20秒 线程C,休眠30秒 2、生产者与消费者问题,生产者生产一台电脑,消费者马上将生 产出的电脑取走。 六、实验小结 1、class MyThread implements Runnable{

String name; int time; public MyThread(String name,int time){ https://www.wendangku.net/doc/5a6948925.html,=name; this.time=time; } public void run(){ try{ Thread.sleep(this.time); } catch(Exception e){ } System.out.println(https://www.wendangku.net/doc/5a6948925.html,+"线程,休眠"+this.time/1000+"秒"); } } public class Demo08{ public static void main(String args[]){ MyThread mt1=new MyThread("线程A",10000); MyThread mt2=new MyThread("线程B",20000); MyThread mt3=new MyThread("线程C",30000);

Java多线程实验报告

实验报告 课程名称: Java语言程序设计 姓名: 学号: 班级: 数学与计算机科学学院

数学与计算机科学学院实验报告实验名称:多线程 指导教师:日期:

if (isPrime) count++; } System.out.println(st + "~" + en + "之间共有" + count + "个质数"); } public static void main(String[] args) { UseThread thread1 = new UseThread(2, 1000); UseThread thread2 = new UseThread(1000, 2000); thread1.start(); thread2.start(); } } 第2题代码: public class Experiment14_2 { public static void main(String[] args) { MyThread t1 = new MyThread("T1"); MyThread t2 = new MyThread("T2"); t1.start(); t2.start(); System.out.println("活动线程数:" + Thread.activeCount()); System.out.println("main()运行完毕"); } } class MyThread extends Thread { public MyThread(String s) { super(s); } public void run() { for (int i = 1; i <= 3; i++) { System.out.println(getName() + "第" + i + "次运行"); try { sleep((int) (Math.random() * 100)); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + "结束"); } }

多线程同步操作多个窗口

多线程同步操作多个窗口 RunApp "notepad.exe" RunApp "notepad.exe" RunApp "notepad.exe" Delay 2000 Dimenv temp_Hwnd temp_Hwnd = 0 Dim str, arr, i str = Plugin.Window.Search("无标题- 记事本") arr = Split(str, "|") For i = 0 To UBound(arr) - 1 temp_Hwnd = Plugin.Window.FindEx(arr(i), 0, "Edit", 0) BeginThread WriteString While temp_Hwnd <> 0'判断多线程已经启动完毕,继续循环下一个。 Delay 500 Wend Next EndScript Function WriteString() Dim str, Hwnd Hwnd = temp_Hwnd temp_Hwnd = 0 Do str = WaitKey If Hwnd <> Plugin.Window.GetKeyFocusWnd Then Call Plugin.Bkgnd.KeyPress(Hwnd, str) End If Loop End Function 多线程多开窗口同步执行与子线程间的数值如何传递: 1.Dimenv IsThread, i 2.Dim arr_Thread() 3.For i = 0 To 2 4. IsThread = False'未启动线程 5. Redim Preserve arr_Thread(i) 6. arr_Thread(i) = BeginThread(EnterThread) 7. While IsThread = False'未启动成功,等待中 8. Delay 500 9. Wend 10. '跳出循环说明 IsThread = True,已经执行到了,循环继续启动下一个 11.Next

线程实验报告

线 程实验报告 黄澄宇320070911241 1.分析 (1)问题阐述,描述。 运用线程的方法设计一个ftp面向客户\服务器的网络应用程序,主要包括服务器端和客户端两方面的工作。 (2)问题分析。 针对问题要求,应该能够实现客户端和服务器端的功能。其中服务器端主要对客户端进行监听。客户端向服务器端进行提出请求。 (3)寻找揭发。 TCP\IP服务器端应用程序都是通过JA V A语言中提供的SeverSocket和Socket两个有关网络的类来实现。 SeverSocket类除了建立一个Sever之外,还通过accept()方法提供了随时监听客户端连接请求的功能。 2.设计。 在服务器端指定一个用来等待连接的端口号,在客户端规定一个主机和端口号,从而在客户端和服务器端创建Socket\ServerSocket实例。

现在服务器端生成一个ServerSocket实例的对象,随时监听客户端的连接请求。 当客户端需要连接时,相应的要生成一个Socket实例的对象,并发出连接请求,其在host参数指明该主机名,port参数指明端口号。 服务器端通过accept()方法接收到客户端的请求后,开辟一个接口与之进行连接,利用输入输出流,按照一定的协议对Socket 进行读写操作。 关闭输入输出流和Socket。 3.实现。 //FTPServer.java import https://www.wendangku.net/doc/5a6948925.html,.*; import java.io.*; import java.util.*; public class FTPServer { public static void main(String args[]) throws Exception { ServerSocket soc=new ServerSocket(5127); System.out.println("FTP Server Started on Port Number "); while(true) {

4:一个经典的多线程同步问题汇总

一个经典的多线程同步问题 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。 要求: 1.子线程输出的线程序号不能重复。 2.全局变量的输出必须递增。 下面画了个简单的示意图: 分析下这个问题的考察点,主要考察点有二个: 1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步。 2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥。 下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。 //经典线程同步互斥问题 #include #include #include long g_nNum; //全局资源 unsigned int__stdcall Fun(void *pPM); //线程函数 const int THREAD_NUM = 10; //子线程个数 int main() { g_nNum = 0;

HANDLE handle[THREAD_NUM]; int i = 0; while (i < THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); i++;//等子线程接收到参数时主线程可能改变了这个i的值} //保证子线程已全部运行结束 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); return 0; } unsigned int__stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来int nThreadNum = *(int *)pPM; //子线程获取参数 Sleep(50);//some work should to do g_nNum++; //处理全局资源 Sleep(0);//some work should to do printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum); return 0; } 运行结果:

Java实验五线程

实验五线程 一实验要求 1、理解进程和线程概念; 2、掌握创建、管理和控制Java线程对象的方法; 3、了解并发执行的多线程存在的各种关系 二实验内容 1、使用线程对象或Timer定时器制作数字时钟标签组件,显示当前日期和时间,每秒刷新,将该标签添加到框架窗口。 import java.awt.FlowLayout; import java.text.SimpleDateFormat;//简单日期格式类 import java.util.Locate; import java.util.Timer;//一种工具,线程用其安排以后在后台线程中执行的任务 import java.util.TimerTask; import java.swing.JLabel; public class ShizhongJFrame extends JFrame{ { Public ShizhongJFrame(){ JFrame f=new JFrame(“数字时钟”); f.setLayout(new FlowLayout()); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(200,70); final JLable lable=new JLable; final SimpleDateFormat format=new SimpleDateFormat(“H:m:s”,Locate.CHINA); f.add(lable); Timer time=new Timer(); time.scheduleAtFixedRate(new TimerTask(){ Public void run(){ Label.setText(format.format(new Date(System.currentTimeMillis()))); } },0,1000); f.setVisible(true); } Public staic void main(String arg[]){ New ShizhogJFrame(); } } 三实验内容中遇到的问题、解决方法和体会。

JAVA线程程序设计(小时钟)实验报告(附完整代码)

线程程序设计 一、课题内容和要求 内容:设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动。 要求:本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力。 二、设计思路分析 class Clock:一个指针式时钟的主类 class Layout: 添加窗口和时钟组件 class ClockPaint:定义时钟组件 三、概要设计 public class Clock extends JFrame { public static void main(String[] s) ; } class Layout extends JFrame { public Layout(); } class ClockPaint extends JPanel implements Runnable { int x, y, r; int h, m, s; double rad = Math.PI / 180; public ClockPaint(int x, int y, int r); public void paint(Graphics g); public void run(); } 时钟的绘制:

运行时钟: 四、详细设计 import java.awt.*; import javax.swing.*; import java.util.*; public class Clock extends JFrame { public static void main(String[] s) { new Layout(); } } class Layout extends JFrame {// 添加窗口和时钟组件public Layout() { ClockPaint cp = new ClockPaint(20, 20, 70); add(cp);

Windows下多线程同步机制

多线程同步机制 Critical section(临界区)用来实现“排他性占有”。适用范围是单一进程的各线程之间。它是: ·一个局部性对象,不是一个核心对象。 ·快速而有效率。 ·不能够同时有一个以上的critical section被等待。 ·无法侦测是否已被某个线程放弃。 Mutex Mutex是一个核心对象,可以在不同的线程之间实现“排他性占有”,甚至几十那些现成分属不同进程。它是: ·一个核心对象。 ·如果拥有mutex的那个线程结束,则会产生一个“abandoned”错误信息。 ·可以使用Wait…()等待一个mutex。 ·可以具名,因此可以被其他进程开启。 ·只能被拥有它的那个线程释放(released)。 Semaphore Semaphore被用来追踪有限的资源。它是: ·一个核心对象。 ·没有拥有者。 ·可以具名,因此可以被其他进程开启。 ·可以被任何一个线程释放(released)。 Ev ent Object Ev ent object通常使用于overlapped I/O,或用来设计某些自定义的同步对象。它是: ·一个核心对象。 ·完全在程序掌控之下。 ·适用于设计新的同步对象。 · “要求苏醒”的请求并不会被储存起来,可能会遗失掉。 ·可以具名,因此可以被其他进程开启。 Interlocked Variable 如果Interlocked…()函数被使用于所谓的spin-lock,那么他们只是一种同步机制。所谓spin-lock是一种busy loop,被预期在极短时间内执行,所以有最小的额外负担(overhead)。系统核心偶尔会使用他们。除此之外,interlocked variables主要用于引用技术。他们:·允许对4字节的数值有些基本的同步操作,不需动用到critical section或mutex之类。 ·在SMP(Symmetric Multi-Processors)操作系统中亦可有效运作。 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

第二章多线程分布式计算课后答案

第二章 1. 选择题 12345678910 D A B C C E C A B B 1112131415161718 B B B C A D A A 2. 程序/方法与进程/线程有什么不同?(53页第四段) 答:一个程序/方法是由程序员写的一段代码,它是静态的。进程/线程是由执行的程序/方法、当前值、状态信息和用于支持它执行的资源构成,资源是它执行时的动态因素。换言之,一个进程/线程是一个动态实体,只有当程序或函数执行时才会存在。 3. 比较多进程(多任务)操作系统和多线程编程环境。(53页5、 6、7段) 答:为了真正并行执行多个进程/线程,必须存在多个处理器。如果系统中只有一个处理器,表面上多个进程/线程执行,实际上实在分时模式下顺序执行。 从同一代码块可以创建多个进程/线程。默认情况下,包含在不同进程/线程中的代码和数据是分离的,每一个都有它自己执行代码的副本、局部变量的栈、对象数据区以及其他数据元素。 通常情况下,一个分布式操作系统可以由不同电脑上的多个实例或副本构成,每一个实例或副本都可以管理多个进程。同样,每个进程可以是由多个线程组成的一个多线程程序。 4. 什么是临界操作?用什么方法可以来保护临界操作?(54页第1 段) 答:对共享资源的访问称为临界操作。虽然一个简单的锁定可以防止共享资源被访问,但是也消除了并行处理的可能性。更理想的方法是不锁定并行读操作,而锁定并行读-写和写-写组合。 5. 什么是死锁?哪些策略可以用来解决死锁问题?(55页) 答:死锁的情况是两个或多个竞争操作等待对方完成,导致都不能完成。 解决方法: (1) 死锁预防:使用一种算法可以保证不会发生死锁。 (2) 死锁避免:使用一种算法,能够遇见死锁的发生从而拒绝资源请求、

第7章 多线程

第7章多线程 7.1 什么是进程?什么是线程?进程与线程的关系是怎样的? 【答】进程:进程是一个可并发的具有独立功能的程序关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位。 线程:线程是操作系统进程中能够独立执行的实体,是处理器调度和分派的基本单位。 线程是进程的组成部分,每个进程内允许包含多个并发执行的线程。 7.2 操作系统为什么要支持多线程技术? 【答】操作系统采用进程机制能够减少程序并发时所付出的时空开销,使得并发粒度更细,并发性更好,提高了资源使用率和系统效率。 7.3 Java为什么要支持线程?什么场合需要使用多线程程序设计? 【答】支持多线程能充分发挥硬件的并发性,消除处理器和I/O设备的互等现象,提高系统效率。一般一下场合需要使用多线程:1、程序包好复杂的计算任务时,主要是利用多线程获取更所得CPU时间。2、处理速度较慢的外围设备。3、程序设计自身的需要。 7.4 Java提供了哪些接口和类实现多线程机制? 【答】Java主要提供了https://www.wendangku.net/doc/5a6948925.html,ng.Runnable接口和Thread线程类来实现多线程机制。 7.5 一个线程对象的生命周期有哪几种状态构成?各状态之间是如何变化的? 【答】 线程对象的生命周期主要包括:新建态、就绪态和运行态、阻塞态和等待态、终止态。新建态通过start()方法是线程成为运行态,当运行态遇到sleep()或wait()方法时就进入等待态,而当sleep()时间到或通过notify()方法线程就又进入了运行态;当运行态遇到synchronized()方法时就进入阻塞态,当线程获得互斥锁使用权时就又到了运行态;当线程的run()方法结束时整个线程就进入了终止态,整个线程结束。 7.6 Java提供了哪些方法能够改变线程状态?程序中能够调度线程立即执行吗?【答】Java中提供了start()方法来启动已创建的线程对象;sleep()方法使当前线程睡眠若干毫秒,线程有运行态进入等待态,但是不交出临界区的锁;yield() 方法暂停当前线程的执行,允许其他线程竞争CPU;stop()方法来结束一个线程;wait()方法将本线程设为等待态;notify() 方法来唤醒当前处于等待态的线程;interrupt()方法改变当前线程的中断状态,但是当前线程还可以继续执行。 7.7 什么是线程的优先级?设置线程优先级有什么作用? 【答】每个线程被执行的优先顺序即为线程的优先级,默认优先级为5。当创建了多个线程并要执行这些线程时,操作系统不知到底该执行哪个线程,当设置好优先级后,程序首先会

第十一章 海上隔水管资料

第十一章海上隔水管 第一节海上隔水管简介 海上隔水管是从海上钻井平台下到海底浅层的套管,是在钻井作业时隔绝海水、循环泥浆的安全通道,上接导流器,下连防喷器,是一组重要的水下钻井装备。在海上石油的勘探中,钻井隔水管是整个钻井系统中重要而又薄弱的环节,是影响海上钻井安全的重要因素。因此隔水管的稳定性对于整个石油的勘探、开采起着重要的作用。 (一)海上隔水管系统主要功能如下: a.隔开海水,提供井口与钻井船之间的液体传输的通道: 1)正常钻井条件下,在隔水管环空内。 2)当BOP组正用于井控时,通过节流和压井管线。 b.支撑节流、压井及辅助管线; c.把工具导向井内; d.作为BOP组的送入和回收管体。 (二)海上隔水管特点: ?工况多变; ?操作频繁; ?深水对钻井隔水管的作用效率与安全有重要的影响; ?其安全性与钻井过程及钻井参数密切相关。 (三)深水隔水管特点: ?结构更为复杂; ?隔水管设计时所考虑的主要因素不同; ?受力状态更加恶劣和复杂,动态响应更为明显,动态分析时与浅水也有很大的不同; ?操作时间长,导致非钻井时间变长,容易出现操作不当导致结构损伤 (四)海上隔水管的失效形式:

1、隔水管灾难性破坏 2、隔水管爆裂 3、隔水管塌陷(静水压溃) 4、涡激振动导致开口破坏 5、隔水管最下部接头处(LMRP上部)断裂 6、隔水管磨损

第二节海上隔水管系统组成及工作原理(一)隔水管系统的组成

(二)海上隔水管系统配套设备 1、卡盘(液压连接装置) 隔水管液压上紧装置放在转盘上,当提起隔水管和连接隔水时,将隔水管柱和BOP组件坐在盘上,卡盘内径和转盘内径相同。其主要作用在于夹紧水管,便于快速连接和拆卸隔水管接头。 隔水管万向节 隔水管万向节放在转盘和卡盘之间,能够支持卡盘、整个隔水管柱和BOP组件的重量,其作用类似于伸缩接头,可以补充由于海流产生的隔水管偏移,便于隔水管连接。 2、分流器(转喷器) 当穿过30英寸套管进行井口钻井时,如有必要,可采用隔水管,使用重泥浆,以提供过平衡。此阶段尚未安装防喷器(BOP)因为一般情况下30英寸的套管还缺少关井所需的足够的压力完善性。因此,如果井自喷,隔水管将把流体导引至钻机上的分流系统。通常,分流系统由环空密封设备、既能打开放气管线又能关闭钻井液返出管的装置以及一个控制系统组成。 3、上部挠性接头(球接头)

1774143105-张强第5章第11次 多线程实验报告

第五章多线程 实验5-1 继承Thread类创建多线程 一、实验描述 1、考核知识点 名称:继承Thread类创建多线程 2、练习目标 掌握如何通过继承Thread类实现多线程的创建。 掌握Thread类中run()方法和start()方法的使用。 3、需求分析 在程序开发中,会遇到一个功能需要多个线程同时执行才能完成的情况。这时,可以通过继承线程类Thread,并重写Thread类中的run()方法来实现。为了让初学者熟悉如何创建多线程,在实验中将通过继承Thread类方式创建线程,并实现多线程分别打印0~99的数字的功能。 4、设计思路(实现原理) 1)自定义一个类Demo,使其继承Thread类。 2)在Demo类中重写run()方法,在run()方法内编写一个for循环,循环体内打印:“Demo:”+ 当前循环次数。 3)编写测试类Example01,在Example01类的main()方法中,创建一个Demo对象,并执行其 start()方法,接着编写一个for循环,循环体内打印:“main:”+当前循环次数。 二、实验实现 class Demo extends Thread { public void run() { for (int x = 0; x < 100; x++) { System.out.println("Demo:"+x); } } } public class Example01{ public static void main(String[] args) { Demo d = new Demo(); d.start(); for(int x=0; x<100; x++){ System.out.println("main:"+x); } }

Java多线程实验报告

实验4:Java多线程 实验时间:实验地点: 一、实验目的及要求 (1)了解线程的概念。 (2)学习简单的多线程编程。 二、实验设备环境及要求 三、实验任务 (1)阅读给定的Java Application程序,按要求回答问题并写出运行结果。 (2)按要求编写一个Java Application程序,并编译、运行这个程序。 四、实验内容与步骤 1.输入下面的Java Application程序,运行该程序,并简要分析程序的运行结果。 1:class SimpleThread extends Thread { 2:public SimpleThread(String str) { 3:super(str); //调用其父类的构造方法 4:} 5:public void run() { //重写run方法 6:for (int i = 0; i < 10; i++) { 7:System.out.println(i + " " + getName()); 8://打印次数和线程的名字 9:try { 10:sleep((int)(Math.random() * 1000)); 11://线程睡眠,把控制权交出去 12:} 13:catch (InterruptedException e) { } 14:} 15:System.out.println("DONE! " + getName()); 16://线程执行结束 17:} 18:}

1:public class TwoThreadsTest { 2:public static void main (String args[]) { 3:new SimpleThread("First").start(); 4://第一个线程的名字为First 5:new SimpleThread("Second").start(); 6://第二个线程的名字为Second 7:} 8:} 2.编写程序,将上面多线程程序用Runnable接口来实现。 class SimpleThread implements Runnable{ public void run(){ for (int i = 0; i < 10; i++){ System.out.println(i + " " + Thread.currentThread().getName()); try { Thread.sleep((int)(Math.random() * 1000)); //线程睡眠,把控制权交出去 } catch (InterruptedException e) { } } System.out.println("DONE! " + Thread.currentThread().getName()); //线程执行结束 } } public class Test { public static void main (String args[]) { /*Thread t1=new Thread("First"); //第一个线程的名字为First Thread t2=new Thread("Second"); //第二个线程的名字为Second t1.start(); t2.start();*/ new Thread(new SimpleThread(),"First").start(); new Thread(new SimpleThread(),"Second").start() } }

Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。 一个进程可以有很多线程,每条线程并行执行不同的任务。 线程可以提高应用程序在多核环境下处理诸如文件I/O或者socket I/O等会产生堵塞的情况的表现性能。在Unix系统中,一个进程包含很多东西,包括可执行程序以及一大堆的诸如文件描述符地址空间等资源。在很多情况下,完成相关任务的不同代码间需要交换数据。如果采用多进程的方式,那么通信就需要在用户空间和内核空间进行频繁的切换,开销很大。但是如果使用多线程的方式,因为可以使用共享的全局变量,所以线程间的通信(数据交换)变得非常高效。 Hello World(线程创建、结束、等待) 创建线程 pthread_create 线程创建函数包含四个变量,分别为: 1. 一个线程变量名,被创建线程的标识 2. 线程的属性指针,缺省为NULL即可 3. 被创建线程的程序代码 4. 程序代码的参数 For example: - pthread_t thrd1? - pthread_attr_t attr? - void thread_function(void argument)? - char *some_argument? pthread_create(&thrd1, NULL, (void *)&thread_function, (void *) &some_argument); 结束线程 pthread_exit 线程结束调用实例:pthread_exit(void *retval); //retval用于存放线程结束的退出状态 线程等待 pthread_join pthread_create调用成功以后,新线程和老线程谁先执行,谁后执行用户是不知道的,这一块取决与操作系统对线程的调度,如果我们需要等待指定线程结束,需要使用pthread_join函数,这个函数实际上类似与多进程编程中的waitpid。 举个例子,以下假设 A 线程调用 pthread_join 试图去操作B线程,该函数将A线程阻塞,直到B线程退出,当B线程退出以后,A线程会收集B线程的返回码。 该函数包含两个参数:pthread_t th //th是要等待结束的线程的标识 void **thread_return //指针thread_return指向的位置存放的是终止线程的返回状态。 调用实例:pthread_join(thrd1, NULL); example1: 1 /************************************************************************* 2 > F i l e N a m e: t h r e a d_h e l l o_w o r l d.c 3 > A u t h o r: c o u l d t t(f y b y) 4 > M a i l: f u y u n b i y i@g m a i l.c o m 5 > C r e a t e d T i m e: 2013年12月14日 星期六 11时48分50秒 6 ************************************************************************/ 7 8 #i n c l u d e 9 #i n c l u d e 10 #i n c l u d e

11 12 v o i d p r i n t_m e s s a g e_f u n c t i o n (v o i d *p t r)? 13 14 i n t m a i n() 15 { 16 i n t t m p1, t m p2?

相关文档 最新文档