当前位置:文档之家› java多线程

java多线程

java多线程
java多线程

转自https://www.doczj.com/doc/ee14782500.html,/62575/27069/作者:熔岩

线程概念与原理

一、操作系统中线程和进程的概念

现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。

进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。

线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe 进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。

“同时”执行是人的感觉,在线程之间实际上轮换执行。

二、Java中的线程

在Java中,“线程”指两件不同的事情:

1、https://www.doczj.com/doc/ee14782500.html,ng.Thread类的一个实例;

2、线程的执行。

使用https://www.doczj.com/doc/ee14782500.html,ng.Thread类或者https://www.doczj.com/doc/ee14782500.html,ng.Runnable接口编写代码来定义、实例化和启动新线程。

一个Thread类实例只是一个对象,像Java中的任何其他对象一样,具有变量和方法,生死于堆上。

Java中,每个线程都有一个调用栈,即使不在程序中创建任何新的线程,线程也在后台运行着。

一个Java应用总是从main()方法开始运行,mian()方法运行在一个线程内,它被称为主线程。

一旦创建一个新的线程,就产生一个新的调用栈。

线程总体分两类:用户线程和守候线程。

当所有用户线程执行完毕的时候,JVM自动关闭。但是守候线程却不独立于JVM,守候线程一般是由操作系统或者用户自己创建的。

线程创建与启动

一、定义线程

1、扩展https://www.doczj.com/doc/ee14782500.html,ng.Thread类。

此类中有个run()方法,应该注意其用法:

public void run()

如果该线程是使用独立的Runnable运行对象构造的,则调用该

Runnable对象的run方法;否则,该方法不执行任何操作并返回。

Thread的子类应该重写该方法。

2、实现https://www.doczj.com/doc/ee14782500.html,ng.Runnable接口。

void run()

使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独

立执行的线程中调用对象的run方法。

方法run的常规协定是,它可能执行任何所需的操作。

二、实例化线程

1、如果是扩展https://www.doczj.com/doc/ee14782500.html,ng.Thread类的线程,则直接new即可。

2、如果是实现了https://www.doczj.com/doc/ee14782500.html,ng.Runnable接口的类,则用Thread的构造方法:Thread(Runnable target)

Thread(Runnable target, String name)

Thread(ThreadGroup group, Runnable target)

Thread(ThreadGroup group, Runnable target, String name)

Thread(ThreadGroup group, Runnable target, String name, long stackSize) 三、启动线程

在线程的Thread对象上调用start()方法,而不是run()或者别的方法。

在调用start()方法之前:线程处于新状态中,新状态指有一个Thread对象,

但还没有一个真正的线程。

在调用start()方法之后:发生了一系列复杂的事情

启动新的执行线程(具有新的调用栈);

该线程从新状态转移到可运行状态;

当该线程获得机会执行时,其目标run()方法将运行。

注意:对Java来说,run()方法没有任何特别之处。像main()方法一样,它只是新线程知道调用的方法名称(和签名)。因此,在 Runnable上或者Thread上调用run方法是合法的。但并不启动新的线程。

四、例子

1、实现Runnable接口的多线程例子

/**

* 实现Runnable接口的类

*

* @author leizhimin 2008-9-13 18:12:10

*/

public class DoSomething implements Runnable {

private String name;

public DoSomething(String name) {

https://www.doczj.com/doc/ee14782500.html, = name;

}

public void run() {

for (int i = 0; i < 5; i++) {

for (long k = 0; k < 100000000; k++) ;

System.out.println(name + ": " + i);

}

}

}

/**

* 测试Runnable类实现的多线程程序

*

* @author leizhimin 2008-9-13 18:15:02

*/

public class TestRunnable {

public static void main(String[] args) {

DoSomething ds1 = new DoSomething("阿三");

DoSomething ds2 = new DoSomething("李四");

Thread t1 = new Thread(ds1);

Thread t2 = new Thread(ds2);

t1.start();

t2.start();

}

}

执行结果:

李四: 0

阿三: 0

李四: 1

阿三: 1

李四: 2

李四: 3

阿三: 2

李四: 4

阿三: 3

阿三: 4

Process finished with exit code 0

2、扩展Thread类实现的多线程例子

/**

* 测试扩展Thread类实现的多线程程序

*

* @author leizhimin 2008-9-13 18:22:13

*/

public class TestThread extends Thread{

public TestThread(String name) {

super(name);

}

public void run() {

for(int i = 0;i<5;i++){

for(long k= 0; k <100000000;k++);

System.out.println(this.getName()+" :"+i); }

}

public static void main(String[] args) {

Thread t1 = new TestThread("阿三");

Thread t2 = new TestThread("李四");

t1.start();

t2.start();

}

}

执行结果:

阿三:0

李四:0

阿三:1

李四:1

阿三:2

李四:2

阿三:3

阿三:4

李四:3

李四:4

Process finished with exit code 0

对于上面的多线程程序代码来说,输出的结果是不确定的。其中的一条语句

for(long k= 0; k <100000000;k++);是用来模拟一个非常耗时的操作的。

五、一些常见问题

1、线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一个是虚拟机自己给的名字,一个是你自己的定的名字。在没有指定线程名字的情况下,虚拟机总会为线程指定名字,并且主线程的名字总是mian,非主线程的名字不确定。

2、线程都可以设置名字,也可以获取线程的名字,连主线程也不例外。

3、获取当前线程的对象的方法是:Thread.currentThread();

4、在上面的代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。

5、当线程目标run()方法结束时该线程完成。

6、一旦线程启动,它就永远不能再重新启动。只有一个新的线程可以被启动,并且只能一次。一个可运行的线程或死线程可以被重新启动。

7、线程的调度是JVM的一部分,在一个CPU的机器上上,实际上一次只能运行一个线程。一次只有一个线程栈执行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。

众多可运行线程中的某一个会被选中做为当前线程。可运行线程被选择运行的顺序是没有保障的。

8、尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列唱呢个一个队列的事实。

9、尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。

线程栈模型与线程的变量

要理解线程调度的原理,以及线程执行过程,必须理解线程栈模型。

线程栈是指某时刻时内存中线程调度的栈信息,当前调用的方法总是位于栈顶。线程栈的内容是随着程序的运行动态变化的,因此研究线程栈必须选择一个运行的时刻(实际上指代码运行到什么地方)。

下面通过一个示例性的代码说明线程(调用)栈的变化过程。

这幅图描述在代码执行到两个不同时刻1、2时候,虚拟机线程调用栈示意图。

当程序执行到t.start();时候,程序多出一个分支(增加了一个调用栈B),这样,栈A、栈B并行执行。

从这里就可以看出方法调用和线程启动的区别了。

线程状态的转换

一、线程状态

线程的状态转换是线程控制的基础。线程状态总的可分为五大状态:分别是生、死、可运行、运行、等待/阻塞。用一个图来描述如下:

1、新状态:线程对象已经创建,还没有在其上调用start()方法。

2、可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。

3、运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。

4、等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。

5、死亡态:当线程的run()方法完成时就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。如果在一个死去的线程上调用start()方法,会抛出

https://www.doczj.com/doc/ee14782500.html,ng.IllegalThreadStateException异常。

有关详细状态转换图可以参看本人的“Java多线程编程总结”中的图

二、阻止线程执行

对于线程的阻止,考虑一下三个方面,不考虑IO阻塞的情况:

睡眠;

等待;

因为需要一个对象的锁定而被阻塞。

1、睡眠

Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。当线程睡眠时,它入睡在某个地方,在苏醒之前不会返回到可运行状态。当睡眠时间到期,则返回到可运行状态。

线程睡眠的原因:线程执行太快,或者需要强制进入下一轮,因为Java规范不保证合理的轮换。

睡眠的实现:调用静态方法。

try {

Thread.sleep(123);

} catch (InterruptedException e) {

e.printStackTrace();

}

睡眠的位置:为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。

例如,在前面的例子中,将一个耗时的操作改为睡眠,以减慢线程的执行。可以这么写:

public void run() {

for(int i = 0;i<5;i++){

// 很耗时的操作,用来减慢线程的执行

// for(long k= 0; k <100000000;k++);

try {

Thread.sleep(3);

} catch (InterruptedException e) {

e.printStackTrace(); .

}

System.out.println(this.getName()+" :"+i);

}

}

运行结果:

阿三:0

李四:0

阿三:1

阿三:2

阿三:3

李四:1

李四:2

阿三:4

李四:3

李四:4

Process finished with exit code 0

这样,线程在每次执行过程中,总会睡眠3毫秒,睡眠了,其他的线程就有机会执行了。

注意:

1、线程睡眠是帮助所有线程获得运行机会的最好方法。

2、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

3、sleep()是静态方法,只能控制当前正在运行的线程。

下面给个例子:

/**

* 一个计数器,计数到100,在每个数字之间暂停1秒,每隔10个数字输出一个字符串

*

* @author leizhimin 2008-9-14 9:53:49

*/

public class MyThread extends Thread {

public void run() {

for (int i = 0; i < 100; i++) {

if ((i) % 10 == 0) {

System.out.println("-------" + i);

}

System.out.print(i);

try {

Thread.sleep(1);

System.out.print(" 线程睡眠1毫秒!\n");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

new MyThread().start(); }

}

-------0

0 线程睡眠1毫秒!

1 线程睡眠1毫秒!

2 线程睡眠1毫秒!

3 线程睡眠1毫秒!

4 线程睡眠1毫秒!

5 线程睡眠1毫秒!

6 线程睡眠1毫秒!

7 线程睡眠1毫秒!

8 线程睡眠1毫秒!

9 线程睡眠1毫秒!

-------10

10 线程睡眠1毫秒!

11 线程睡眠1毫秒!

12 线程睡眠1毫秒!

13 线程睡眠1毫秒!

14 线程睡眠1毫秒!

15 线程睡眠1毫秒!

16 线程睡眠1毫秒!

17 线程睡眠1毫秒!

18 线程睡眠1毫秒!

19 线程睡眠1毫秒!

-------20

20 线程睡眠1毫秒!

21 线程睡眠1毫秒!

22 线程睡眠1毫秒!

23 线程睡眠1毫秒!

24 线程睡眠1毫秒!

25 线程睡眠1毫秒!

26 线程睡眠1毫秒!

27 线程睡眠1毫秒!

28 线程睡眠1毫秒!

29 线程睡眠1毫秒!

-------30

30 线程睡眠1毫秒!

31 线程睡眠1毫秒!

32 线程睡眠1毫秒!

33 线程睡眠1毫秒!

34 线程睡眠1毫秒!

35 线程睡眠1毫秒!

37 线程睡眠1毫秒!

38 线程睡眠1毫秒!

39 线程睡眠1毫秒!-------40

40 线程睡眠1毫秒!

41 线程睡眠1毫秒!

42 线程睡眠1毫秒!

43 线程睡眠1毫秒!

44 线程睡眠1毫秒!

45 线程睡眠1毫秒!

46 线程睡眠1毫秒!

47 线程睡眠1毫秒!

48 线程睡眠1毫秒!

49 线程睡眠1毫秒!-------50

50 线程睡眠1毫秒!

51 线程睡眠1毫秒!

52 线程睡眠1毫秒!

53 线程睡眠1毫秒!

54 线程睡眠1毫秒!

55 线程睡眠1毫秒!

56 线程睡眠1毫秒!

57 线程睡眠1毫秒!

58 线程睡眠1毫秒!

59 线程睡眠1毫秒!-------60

60 线程睡眠1毫秒!

61 线程睡眠1毫秒!

62 线程睡眠1毫秒!

63 线程睡眠1毫秒!

64 线程睡眠1毫秒!

65 线程睡眠1毫秒!

66 线程睡眠1毫秒!

67 线程睡眠1毫秒!

68 线程睡眠1毫秒!

69 线程睡眠1毫秒!-------70

70 线程睡眠1毫秒!

71 线程睡眠1毫秒!

72 线程睡眠1毫秒!

73 线程睡眠1毫秒!

74 线程睡眠1毫秒!

75 线程睡眠1毫秒!

77 线程睡眠1毫秒!

78 线程睡眠1毫秒!

79 线程睡眠1毫秒!

-------80

80 线程睡眠1毫秒!

81 线程睡眠1毫秒!

82 线程睡眠1毫秒!

83 线程睡眠1毫秒!

84 线程睡眠1毫秒!

85 线程睡眠1毫秒!

86 线程睡眠1毫秒!

87 线程睡眠1毫秒!

88 线程睡眠1毫秒!

89 线程睡眠1毫秒!

-------90

90 线程睡眠1毫秒!

91 线程睡眠1毫秒!

92 线程睡眠1毫秒!

93 线程睡眠1毫秒!

94 线程睡眠1毫秒!

95 线程睡眠1毫秒!

96 线程睡眠1毫秒!

97 线程睡眠1毫秒!

98 线程睡眠1毫秒!

99 线程睡眠1毫秒!

Process finished with exit code 0

2、线程的优先级和线程让步yield()

线程的让步是通过Thread.yield()来实现的。yield()方法的作用是:暂停当前正在执行的线程对象,并执行其他线程。

要理解yield(),必须了解线程的优先级的概念。线程总是存在优先级,优先级范围在1~10之间。JVM线程调度程序是基于优先级的抢先调度机制。在大多数情况下,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。但这仅仅是大多数情况。

注意:当设计多线程应用程序的时候,一定不要依赖于线程的优先级。因为线程调度优先级操作是没有保障的,只能把线程优先级作用作为一种提高程序效率的方法,但是要保证程序不依赖这种操作。

当线程池中线程都具有相同的优先级,调度程序的JVM实现自由选择它喜欢的线程。这时候调度程序的操作有两种可能:一是选择一个线程运行,直到它阻塞或者运行完成为止。二是时间分片,为池内的每个线程提供均等的运行机会。

设置线程的优先级:线程默认的优先级是创建它的执行线程的优先级。可以通过setPriority(int newPriority)更改线程的优先级。例如:

Thread t = new MyThread();

t.setPriority(8);

t.start();

线程优先级为1~10之间的正整数,JVM从不会改变一个线程的优先级。然而,1~10之间的值是没有保证的。一些JVM可能不能识别10个不同的值,而将这些优先级进行每两个或多个合并,变成少于10个的优先级,则两个或多个优先级的线程可能被映射为一个优先级。

线程默认优先级是5,Thread类中有三个常量,定义线程优先级范围:

static int MAX_PRIORITY

线程可以具有的最高优先级。

static int MIN_PRIORITY

线程可以具有的最低优先级。

static int NORM_PRIORITY

分配给线程的默认优先级。

3、Thread.yield()方法

Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

4、join()方法

Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作。例如:

Thread t = new MyThread();

t.start();

t.join();

另外,join()方法还有带超时限制的重载版本。例如t.join(5000);则让线程等待5000毫秒,如果超过这个时间,则停止等待,变为可运行状态。

线程的加入join()对线程栈导致的结果是线程栈发生了变化,当然这些变化都是瞬时的。下面给示意图:

小结

到目前位置,介绍了线程离开运行状态的3种方法:

1、调用Thread.sleep():使当前线程睡眠至少多少毫秒(尽管它可能在指定的时间之前被中断)。

2、调用Thread.yield():不能保障太多事情,尽管通常它会让当前运行线程回到可运行性状态,使得有相同优先级的线程有机会执行。

3、调用join()方法:保证当前线程停止执行,直到该线程所加入的线程完成为止。然而,如果它加入的线程没有存活,则当前线程不需要停止。

除了以上三种方式外,还有下面几种特殊情况可能使线程离开运行状态:

1、线程的run()方法完成。

2、在对象上调用wait()方法(不是在线程上调用)。

3、线程不能在对象上获得锁定,它正试图运行该对象的方法代码。

4、线程调度程序可以决定将当前运行状态移动到可运行状态,以便让另一个线程获得运行机会,而不需要任何理由。

线程同步于锁

线程的交互

线程的调度-休眠线程的调度-优先级线程的调度-让步

线程的调度-合并

线程的调度-守护线程

线程的调度-同步方法

线程的调度-同步块

并发协作-生产者与消费者

并发协作-死锁

volatile关键字

线程池

有返回值的线程

锁(上)

锁(下)

信号量

阻塞队列

阻塞栈

条件变量

原子量

障碍器

大总结

Java第七单元练习题-Java多线程机制

7Java多线程机制 7.1单项选择题 1. 线程调用了sleep()方法后,该线程将进入()状态。 A. 可运行状态 B. 运行状态 C. 阻塞状态 D. 终止状态 2. 关于java线程,下面说法错误的是() A. 线程是以CPU为主体的行为 B. java利用线程使整个系统成为异步 C. 创建线程的方法有两种:实现Runnable接口和继承Thread类 D. 新线程一旦被创建,它将自动开始运行 3. 在java中的线程模型包含() A. 一个虚拟处理器 B. CPU执行的代码 C. 代码操作的数据 D. 以上都是 4.在java语言中,临界区可以是一个语句块,或者是一个方法,并用()关键字标识。 A. synchronized B. include C. import D. Thread 5. 线程控制方法中,yield()的作用是() A. 返回当前线程的引用 B. 使比其低的优先级线程执行 C. 强行终止线程 D. 只让给同优先级线程运行 6. 线程同步中,对象的锁在()情况下持有线程返回 A. 当synchronized()语句块执行完后 B. 当在synchronized()语句块执行中出现例外(exception)时 C. 当持有锁的线程调用该对象的wait()方法时 D. 以上都是 7. 在以下()情况下,线程就进入可运行状态 A. 线程调用了sleep()方法时 B. 线程调用了join()方法时

C. 线程调用了yield()方法时 D. 以上都是 8. java用()机制实现了进程之间的异步执行 A. 监视器 B. 虚拟机 C. 多个CPU D. 异步调用 类的方法中,toString()方法的作用是() A. 只返回线程的名称 B. 返回当前线程所属的线程组的名称 C. 返回当前线程对象 D. 返回线程的名称 语言具有许多优点和特点,下列选项中,哪个反映了Java程序并行机制的特点() A. 安全性 B. 多线程 C. 跨平台 D. 可移值 11.以下哪个关键字可以用来对对象加互斥锁?() A. transient B. synchronized C. serialize D. static 12.下面关于进程、线程的说法不正确的是( )。 A.进程是程序的一次动态执行过程。一个进程在其执行过程中,可以产生多个线程——多线程,形成多条执行线索。 B.线程是比进程更小的执行单位,是在一个进程中独立的控制流,即程序内部的控制流。线程本身不能自动运行,栖身于某个进程之中,由进程启动执行。 C.Java多线程的运行与平台无关。 D.对于单处理器系统,多个线程分时间片获取CPU或其他系统资源来运行。对于多处理器系统,线程可以分配到多个处理器中,从而真正的并发执行多任务。 7.2填空题 1.________是java程序的并发机制,它能同步共享数据、处理不同的事件。 2.线程是程序中的一个执行流,一个执行流是由CPU运行程序的代码、__________所形 成的,因此,线程被认为是以CPU为主体的行为。 3.线程的终止一般可以通过两种方法实现:自然撤销或者是__________. 4.线程模型在java中是由__________类进行定义和描述的。 5.线程的创建有两种方法:实现_________接口和继承Thread类。 6.多线程程序设计的含义是可以将程序任务分成几个________的子任务。 7.按照线程的模型,一个具体的线程也是由虚拟的CPU、代码与数据组成,其中代码与数 据构成了___________,线程的行为由它决定。 8.ava中,新建的线程调用start()方法、如(),将使线程的状态从New(新建状态)转换为 _________。 9.多线程是java程序的________机制,它能同步共享数据,处理不同事件。 10.进程是由代码、数据、内核状态和一组寄存器组成,而线程是表示程序运行状态的

Java_2实用教程第4版_第12章_Java多线程机制

2014/1/20 第 1 页 注意:开始用功了! 1 2014/1/20 第 2 页 《Java2实用教程(第4版)》第12章 配合例子源代码一起使用 Power point 制作:耿祥义张跃平 Java多线程机制 2 2014/1/20 第 3 页 导读 主要内容 Java中的线程 Thread类与线程的创建 线程的常用方法 线程同步 协调同步的线程 线程联合 GUI线程 计时器线程 3 2014/1/20 第 4 页 §12.1 进程与线程 §12.1.1 操作系统与进程 程序是一段静态的代码,它是应用软件执行的蓝本。 进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。 现代操作系统可以同时管理一个计算机系统中的多个进程,即可以让计算机系统中的多个进程轮流使用CPU资源。 4 2014/1/20 第 5 页 §12.1.2 进程与线程 线程是比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程。 线程间可以共享进程中的某些内存单元(包括代码与数据),线程的中断与恢复可以更加节省系统的开销。 5 2014/1/20 第 6 页

§12.2 Java中的线程 §12.2.1 Java的多线程机制 Java语言的一大特性点就是内置对多线程的支持。 Java虚拟机快速地把控制从一个线程切换到另一个线程。这些线程将被轮流执行,使得每个线程都有机会使用CPU资源。 6 2014/1/20 第7 页 §12.2.2 主线程(main线程) 每个Java应用程序都有一个缺省的主线程。 当JVM(Java Virtual Machine 虚拟机)加载代码,发现main方法之后,就会启动一个线程,这个线程称为“主线程”(main线程),该线程负责执行main方法。 JVM一直要等到Java应用程序中的所有线程都结束之后,才结束Java应用程序。 7 2014/1/20 第8 页 §12.2.3 线程的状态与生命周期 建的线程在它的一个完整的生命周期中通常要经历如下的四种状态: 1.新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。2.运行:线程必须调用start()方法(从父类继承的方法)通知JVM,这样JVM就会知道又有一个新一个线程排队等候切换了。一旦轮到它来享用CPU资源时,此线程的就可以脱离创建它的主线程独立开始自己的生命周期了。 3.中断:有4种原因的中断: ◆JVM将CPU资源从当前线程切换给其他线程,使本线程让出CPU的使用权处于中断状态。 ◆线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状。 ◆线程使用CPU资源期间,执行了wait()方法。 ◆线程使用CPU资源期间,执行某个操作进入阻塞状态。 4.死亡:处于死亡状态的线程不具有继续运行的能力。线程释放了实体。 8 2014/1/20 第9 页 例子1(Example12_1.java )通过分析运行结果阐述线程的4种状态。例子1在主线程中用Thread的子类创建了两个线程(SpeakElephant.java , SpeakCar.java ),这两个线程分别在命令行窗口输出20句“大象”和“轿车”;主线程在命令行窗口输出15句“主人”。 例子1的运行效果如图12.4。 例子1在不同的计算机运行或在同一台计算机反复运行的结果不尽相同,输出结果依赖当前CPU资源的使用情况。 9 2014/1/20 第10 页 §12.2.4 线程调度与优先级 处于就绪状态的线程首先进入就绪队列排队等候CPU资源,同一时刻在就绪队列中的线程可能有多个。Java虚拟机(JVM)中的线程调度器负责管理线程,调度器把线程的优先

java线程练习题及答案

线程与线程类 1 线程的概念 线程的概念来源于计算机的操作系统的进程的概念。进程是一个程序关于某个数据集的一次运行。也就是说,进程是运行中的程序,是程序的一次运行活动。 线程和进程的相似之处在于,线程和运行的程序都是单个顺序控制流。有些教材将线程称为轻量级进程(light weight process)。线程被看作是轻量级进程是因为它运行在一个程序的上下文内,并利用分配给程序的资源和环境。 作为单个顺序控制流,线程必须在运行的程序中得到自己运行的资源,如必须有自己的执行栈和程序计数器。线程内运行的代码只能在该上下文内。因此还有些教程将执行上下文(execution context)作为线程的同义词。 所有的程序员都熟悉顺序程序的编写,如我们编写的名称排序和求素数的程序就是顺序程序。顺序程序都有开始、执行序列和结束,在程序执行的任何时刻,只有一个执行点。线程(thread )则是进程中的一个单个的顺序控制流。单线程的概念很简单,如图1所示。 多线程(multi-thread )是指在单个的程序内可以同时运行多个不同的线程完成不同的任务,图2说明了一个程序中同时有两个线程运行。 图1 单线程程序示意图 图2 多线程程序示意图 有些程序中需要多个控制流并行执行。例如, for(int i = 0; i < 100; i++) System.out.println("Runner A = " + i); for(int j = 0; j < 100; j++ ) System.out.println("Runner B = "+j); 上面的代码段中,在只支持单线程的语言中,前一个循环不执行完不可能执行第二个循环。要使两个循环同时执行,需要编写多线程的程序。 很多应用程序是用多线程实现的,如Hot Java Web 浏览器就是多线程应用的例子。在Hot Java 浏览器中,你可以一边滚动屏幕,一边下载Applet 或图像,可以同时播放动画和声音等。 2 Thread 类和Runnable 接口 多线程是一个程序中可以有多段代码同时运行,那么这些代码写在哪里,如何创建线程对象呢? 首先,我们来看Java 语言实现多线程编程的类和接口。在https://www.doczj.com/doc/ee14782500.html,ng 包中定义了Runnable 接口和Thread 类。

Java第七单元练习题Java多线程机制

J a v a第七单元练习题 J a v a多线程机制 The latest revision on November 22, 2020

7Java多线程机制 7.1单项选择题 1. 线程调用了sleep()方法后,该线程将进入()状态。 A. 可运行状态 B. 运行状态 C. 阻塞状态 D. 终止状态 2. 关于java线程,下面说法错误的是() A. 线程是以CPU为主体的行为 B. java利用线程使整个系统成为异步 C. 创建线程的方法有两种:实现Runnable接口和继承Thread类 D. 新线程一旦被创建,它将自动开始运行 3. 在java中的线程模型包含() A. 一个虚拟处理器 B. CPU执行的代码 C. 代码操作的数据 D. 以上都是 4.在java语言中,临界区可以是一个语句块,或者是一个方法,并用()关键字标识。 A. synchronized B. include C. import D. Thread 5. 线程控制方法中,yield()的作用是() A. 返回当前线程的引用 B. 使比其低的优先级线程执行 C. 强行终止线程 D. 只让给同优先级线程运行 6. 线程同步中,对象的锁在()情况下持有线程返回 A. 当synchronized()语句块执行完后 B. 当在synchronized()语句块执行中出现例外(exception)时 C. 当持有锁的线程调用该对象的wait()方法时 D. 以上都是 7. 在以下()情况下,线程就进入可运行状态 A. 线程调用了sleep()方法时 B. 线程调用了join()方法时 C. 线程调用了yield()方法时 D. 以上都是 8. java用()机制实现了进程之间的异步执行

java多线程实现调度

重庆交通大学综合性设计性实验报告 实验项目名称:进程调度(先来先服务) 实验项目性质: JAVA多线程 实验所属课程: JAVA程序设计 实验室(中心):语音大楼 8 楼 801 班级:软件专业 2012级2班 姓名:尚亚* 学号: 631206050216 指导教师:杨 实验完成时间: 2014 年 11 月 25 日

一、实验目的 1、理解程序、线程和进程的概念; 2、理解多线程的概念; 3、掌握线程的各种状态; 4、熟练使用Thread类创建线程; 5、熟练使用线程各种方法; 6、掌握线程的调度及线程同步的实现原理。 二、实验内容及要求 进程调度是处理机管理的核心内容。本实验要求采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法编写和调试一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念。并体会了优先数和先来先服务调度算法的具体实施办法。 用JA V A语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。做一个能够直观体现多个进程时,CPU 是怎样调度就绪队列中的进程(按照先来先服务的原则)。

三、实验设备 PC机,windows7,eclipse。 四、设计方案 ㈠设计主要思想 (1)要模拟进程的调度算法,必须先体现处进程及系统资源。 (2)要体现先来先服务的算法,就必须表现出当有一个进程进入CPU时其他进程不能进入,并在就绪队列中排队。本实验建立了四个圆移动的线程表示作业调度,用圆在表示就绪队列的方框中停留表示进程在就绪队列中排队。 (3)当有一个圆移动到表示CPU的范围内时,让其它线程在就绪队列中排队,当CPU内无进程时,先来的圆先移动,以表示CPU 对进程的调度。 ㈡设计的主要步骤 (1)建立四个不同颜色的圆移动的线程,表示对四个进程的调度。 (2)当有一个表示进程的圆到达表示CPU范围内时,通过让其它几个圆停留在表示就绪队列的方框范围内,表示进程在就绪队列中排成队列。 (3)当第一个先到达的进程释放CPU,在排成队列的几个圆中选择先到达的圆,使其移动表示对先来的进程进行调度,直到所有的圆移动完毕。 五、主要代码 import java.awt.Font; import java.awt.event.*;

Java第七单元练习题Java多线程机制(20210109223217)

7 Java 多线程机制 7.1 单项选择题 1. 线程调用了sleep ()方法后,该线程将进入( )状态。 A. 可运行状态 B. 运行状态 C. 阻塞状态 D. 终止状态 2. 关于java 线程,下面说法错误的是() A. 线程是以CPU为主体的行为 B. java 利用线程使整个系统成为异步 C. 创建线程的方法有两种:实现Runnable 接口和继承Thread 类 D. 新线程一旦被创建,它将自动开始运行 3. 在java 中的线程模型包含() A. 一个虚拟处理器 B. CPU执行的代码 C. 代码操作的数据 D. 以上都是 4. 在java 语言中,临界区可以是一个语句块,或者是一个方法,并用()关键字标识。 A. synchronized B. include C. import D. Thread 5. 线程控制方法中,yield()的作用是() A. 返回当前线程的引用 B. 使比其低的优先级线程执行 C. 强行终止线程 D. 只让给同优先级线程运行 6. 线程同步中,对象的锁在()情况下持有线程返回 A. 当synchronized()语句块执行完后 B. 当在synchronized()语句块执行中出现例外( exception )时 C. 当持有锁的线程调用该对象的wait()方法时 D. 以上都是 7. 在以下()情况下,线程就进入可运行状态 A. 线程调用了sleep()方法时 B. 线程调用了join()方法时 C. 线程调用了yield()方法时 D. 以上都是 8. java 用()机制实现了进程之间的异步执行 A. 监视器 B. 虚拟机

Java学习笔记(Java名词解释和多线程编程)

名词解释 & JAVA多线程编程 名词解释: JNI(Java Native Interface)指的是Java本地调用接口,通过这一接口,Java程序可以和采用其他语言编写的本地程序进行通信。 IPC是两个进程之间进行通信的一种机制。 JMX(Java Management Extensions)是SUN提出的Java管理扩展规范,是一个为应用程序、设备和系统植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议。通过JMX,用户可以灵活地开发无缝集成的系统、网络和服务管理应用。 JNDI(Java Naming and Directory Interface)是一种将对象和名字绑定的技术,对象工厂负责生产出对象,这些对象都和惟一的名字绑定。外部程序可以通过名字来获得某个对象的引用。 DTD即文档类型定义。 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,是Internet 传送E-mail的基本协议,也是TCP/IP协议组的成员。SMTP解决了E-mail系统

如何通过一条链路,把邮件从一台机器传递到另一台机器上的问题。通常把发送邮件服务器称为SMTP服务器。 POP3(Post Office Protocol3)即邮局协议第3版,这是Internet接收E-mail 的基本协议,也是TCP/IP协议组的成员。 IMAP(Internet Message Access Protocol)即直接收取邮件的协议,是与POP3不同的一种E-mail接收的新协议。 MIME(Multipurpose Internet Mail Extensions)是一种电子邮件编码方式,它可以将发信人的电子邮件中的文本以及各种附件都打包后发送。 SOAP(Simple Object Access Protocol)即简单对象访问协议,是在分散或分布式的环境中交换信息的简单协议,它以XML作为数据传送方式。 OOP即面向对象程序设计 OOA(Object Oriented Analysis)即面向对象的分析。 OOD(Object Oriented Design)即面向对象的设计。 OOI(Object Oriented Implementation)即面向对象的实现。

JAVA多线程编程详解-详细操作例子

一、理解多线程 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。 具体到java内存模型,由于Java被设计为跨平台的语言,在内存管理上,显然也要有一个统一的模型。系统存在一个主内存(Main Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。 多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独

立,使得各个线程之间的代码是乱序执行的,将会带来线程调度,同步等问题。 二、在Java中实现多线程 我们不妨设想,为了创建一个新的线程,我们需要做些什么?很显然,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切! 作为一个完全面向对象的语言,Java提供了类https://www.doczj.com/doc/ee14782500.html,ng.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程。 那么如何提供给Java 我们要线程执行的代码呢?让我们来看一看Thread 类。Thread 类最重要的方法是run (),它为Thread 类的方法start()所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它! 方法一:继承Thread 类,重写方法run(),我们在创建Thread 类的子类中重写run(),加入线程所要执行的代码即可。下面是一个例子:

java多线程 练习

1.如果线程死亡,它便不能运行。(T) 2.在Java中,高优先级的可运行线程会抢占低优先级线程。(T ) 3.线程可以用yield方法使低优先级的线程运行。(F) 4...程序开发者必须创建一个线程去管理内存的分配。(F) 5.一个线程在调用它的start方法,之前,该线程将一直处于出生期。(T) 6.当调用一个正在进行线程的stop( )方法时,该线程便会进入休眠状态。(F) 7.一个线程可以调用yield方法使其他线程有机会运行。(T) 二、选择题 1.Java语言中提供了一个▁D▁线程,自动回收动态分配的内存。 A.异步 B.消费者 C.守护 D.垃圾收集 2.Java语言避免了大多数的▁C▁错误。 A.数组下标越界 B.算术溢出 C.内存泄露 D.非法的方法参数 3.有三种原因可以导致线程不能运行,它们是▁ACD▁▁。 A.等待 B.阻塞 C.休眠 D.挂起及由于I/O操作而阻塞 4.当▁A方法终止时,能使线程进入死亡状态。 A.run B.setPrority C.yield D.sleep 5.用▁B▁方法可以改变线程的优先级。 A.run B.setPrority C.yield D.sleep 6.线程通过▁C▁方法可以使具有相同优先级线程获得处理器。 A.run B.setPrority C.yield D.sleep 7.线程通过▁D▁方法可以休眠一段时间,然后恢复运行。 A.run B.setPrority C.yield

8.方法resume( )负责重新开始▁D▁线程的执行。 A.被stop( )方法停止 B.被sleep( )方法停止 C.被wait( )方法停止 D.被suspend( )方法停止 9.▁BCD▁方法可以用来暂时停止当前线程的运行。 A.stop( ) B.sleep( ) C.wait( ) D.suspend( ) 三、简述题 1.简述程序、进程和线程之间的关系?什么是多线程程序? 答:程序是一段静态的代码,它是应用软件执行的蓝本。进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程。这个过程也是进程本身从产生、发展、到消亡的过程。线程是比进程更小的单位。一个进程在其执行过程中,可以产生多个线程,形成多个执行流。每个执行流即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。多线程程序是指一个程序中包含多个执行流。 2.线程有哪几个基本状态?它们之间如何转化?简述线程的生命周期。 答:新建状态,可运行状态,运行状态,阻碍状态,终止状态。对线程调用各种控制方法,就使线程从一种状态转换到另一种状态。线程的生命周期从新建开始,在可运行、运行和其他阻碍中循环,在可运行、运行、对象锁阻塞、等待阻塞中循环,最终在运行后run()方法结束后终止。 3.什么是线程调度?Java的线程调度采用什么策略? 答:在单个CPU上以某种顺序运行多个线程,称为线程的调度。Java的线程调度策略是一种优先级的抢先式调度。Java基于线程的优先级选择高优先级的线程进行运行。该线程将持续运行,直到它终止运行,或其他高优先级线程称为可运行的。 4.如何在Java程序中实现多线程? 答:1:通过Thread类的构造方法 2:通过实现Runnable接口创建线程、 3:通过继承Thread类创建线程 5.试简述Thread类的子类或实现Runnable接口两种方法的异同? 答:采用继承Thread类方法使程序代码简单,并可以在run()方法中直接调用线程的其他方法。而实现Runnable接口更符合面向对象设计的思想,因为从OO设计的角度,thread 类是虚拟CPU的封装,所以Thread的子类应该是关于CPU行为的类。但在继承Thread类之类构造线程的方法中,Thread类的子类大都是与CPU不相关的类。而实现Runnable接口的方法,将不影响Java类的体系,所以更加符合面向对象的设计思想。同时,实现了Runnable 接口的类可以用extends继承其他的类。 四、程序设计题 1.编写一个类,在类中定义: A:一个整型属性

JAVA多线程简单案例.

第一页在 Java 程序中使用多线程要比在 C 或 C++ 中容易得多,这是因为Java 编程语言提供了语言级的支持。本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观。读完本文以后,用户应该能够编写简单的多线程程序。 为什么会排队等待?下面的这个简单的 Java 程序完成四项不相关的任务。这样的程序有单个控制线程,控制在这四个任务之间线性地移动。此外,因为所需的资源 ? 打印机、磁盘、数据库和显示屏 -- 由于硬件和软件的限制都有内在的潜伏时间,所以每项任务都包含明显的等待时间。因此,程序在访问数据库之前必须等待打印机完成打印文件的任务,等等。如果您正在等待程序的完成,则这是对计算资源和您的时间的一种拙劣使用。改进此程序的一种方法是使它成为多线程的。四项不相关的任务class myclass { static public void main(String args[] { print_a_file(; manipulate_another_file(; access_database(; draw_picture_on_screen(; } } 在本例中,每项任务在开始之前必须等待前一项任务完成,即使所涉及的任务毫不相关也是这样。但是,在现实生活中,我们经常使用多线程模型。我们在处理某些任务的同时也可以让孩子、配偶和父母完成别的任务。例如,我在写信的同时可能打发我的儿子去邮局买邮票。用软件术语来说,这称为多个控制(或执行)线程。可以用两种不同的方法来获得多个控制线程:多个进程在大多数操作系统中都可以创建多个进程。当一个程序启动时,它可以为即将开始的每项任务创建一个进程,并允许它们同时运行。当一个程序因等待网络访问或用户输入而被阻塞时,另一个程序还可以运行,这样就增加了资源利用率。但是,按照这种方式创建每个进程要付出一定的代价:设置一个进程要占用相当一部分处理器时间和内存资源。而且,大多数操作系统不允许进程访问其他进程的内存空间。因此,进程间的通信很不方便,并且也不会将它自己提供给容易的编程模型。线程线程也称为轻型进程 (LWP。因为线程只能在单个进程的作用域内活动,所以创建线程比创建进程要廉价得多。这样,因为线程允许协作和数据交换,并且在计算资源方面非常廉价,所以线程比进程更可取。线程需要操作系统的支持,因此不是所有的机器都提供线程。Java 编程语言,作为相当新的一种语言,已将线程支持与语言本身合为一体,这样就对线程提供了强健的支持。使用 Java 编程语言实现线程Jav

(参考答案版)福建农林大学_java_实验七_多线程

Java面向对象程序设计 实验七 多线程 学号: 姓名: 学院:计算机与信息学院 专业班级: 指导老师:林志伟 2 015.12.3

1 .单线程实例的运行结果是: mainbegins12345678910111213141516171819202122 2 324252627282930313233343536373839404142434445 647484950ABCDEFGHIJKLMNOPQRSTUVWXYZa 4 bcdefghijklmnopqrstuvwxyzmainends 多线程视力的运行结果是: mainbeginsmainendsA1B2C3D4E5F6G7H8I9JKLMNO PQRS 10 T11U 12 V13 W 14X15 Y16Z 17 a18b 19 c20 d 21e22 f 23 g24 h25i 26j 27k 28l 29m30n31o32p33q34r35 s36 t 37u38v39w40x41y42z4344454647484950 多线程与单线程的区别在于多线程可以同时运行多段代码,提高程序的执行 效率。 2 .程序运行结果如下: mainprint0 Thread1print5 Thread1print6 Thread1print7 Thread1print8 Thread1print9 Thread2print0 Thread2print1 Thread2print2 Thread2print3 Thread2print4 Thread2print5 Thread2print6 Thread2print7 Thread2print8 Thread2print9 mainprint1 mainprint2 mainprint3 mainprint4 mainprint5 mainprint6 mainprint7 mainprint8 mainprint9 Thread1print0 Thread1print1 Thread1print2 Thread1print3 Thread1print4 Threads 类实现了Runnable 接口,故程序运行到了t1.start()时会创建一个新 的线程并运行t1.run()内部的代码,运行到t2.start()时会再创建一个新的线程, 并运行t2.run()内部的代码。虽然这个程序是多线程的,但是由于cpu 运行速 度过快,导致这个程序的运行结果跟单线程运行的结果没有区别。当将run() 方法中的循环次数增加到了100 时,就可以看出多线程运行结果与单线程运 行结果的不同了。

JAVA多线程编程(详细操作例子)(低分分享)

多线程 一、理解多线程 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。 具体到java内存模型,由于Java被设计为跨平台的语言,在内存管理上,显然也要有一个统一的模型。系统存在一个主内存(Main Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。 多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,将会带来线程调度,同步等问题。 二、在Java中实现多线程 我们不妨设想,为了创建一个新的线程,我们需要做些什么?很显然,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切! 作为一个完全面向对象的语言,Java提供了类https://www.doczj.com/doc/ee14782500.html,ng.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程。 那么如何提供给Java 我们要线程执行的代码呢?让我们来看一看Thread 类。Thread 类最重要的方法是run(),它为Thread 类的方法start()所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它! 方法一:继承Thread 类,重写方法run(),我们在创建Thread 类的子类中重写run (),加入线程所要执行的代码即可。下面是一个例子: public class TwoThread extends Thread { public void run() { for ( int i = 0; i < 10; i++ ) { System.out.println("New thread"); } } public static void main(String[] args) { TwoThread tt = new TwoThread();

7Java第七单元练习测试题-Java多线程机制

7J a v a多线程机制7.1单项选择题 1. 线程调用了sleep()方法后,该线程将进入()状态。 A. 可运行状态 B. 运行状态 C. 阻塞状态 D. 2. 关于 A. C. D. 3. 在 A. C. D. 4.在 5. A. B. C. D. 6. A. 当 B. C. 当持有锁的线程调用该对象的wait()方法时 D. 以上都是 7. 在以下()情况下,线程就进入可运行状态 A. 线程调用了sleep()方法时 B. 线程调用了join()方法时 C. 线程调用了yield()方法时 D. 以上都是 8. java用()机制实现了进程之间的异步执行 A. 监视器 B. 虚拟机 C. 多个CPU

D. 异步调用 9.Thread类的方法中,toString()方法的作用是() A. 只返回线程的名称 B. 返回当前线程所属的线程组的名称 C. 返回当前线程对象 D. 返回线程的名称 10.Java语言具有许多优点和特点,下列选项中,哪个反映了Java程序并行机制的特点() A. 安全性 B. 多线程 C. 跨平台 D. 可移值 11. 12. A B C.Java D 7.2 1. 2.因 3. 4. 5. 6. 7. 了 8.ava)转 换为_________。 9.多线程是java程序的________机制,它能同步共享数据,处理不同事件。 10.进程是由代码、数据、内核状态和一组寄存器组成,而线程是表示程序运行状态的______,如 程序计数器、栈指针以及堆栈组成。 11.Thread类提供了一系列基本线程控制方法,如果我们需要让与当前进程具有相同优先级的线程 也有运行的机会则可以调用________方法。 12.在多线程系统中,多个线程之间有________和互斥两种关系。 13. 在一个时间只能由一个线程访问的资源称为临界资源,访问临界资源的代码___________。

15个顶级Java多线程面试题及答案

15个顶级Java多线程面试题及答案 1)现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行 这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。这个多线程问题比较简单,可以用join方法实现。 2)在Java中Lock接口比synchronized块的优势是什么你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它 lock接口在多线程和并发编程中最大的优势是它们为读和写分别提供了锁,它能满足你写像ConcurrentHashMap这样的高性能数据结构和有条件的阻塞。Java线程面试的问题越来越会根据面试者的回答来提问。我强烈建议在你去参加多线程的面试之前认真读一下Locks,因为当前其大量用于构建电子交易终统的客户端缓存和交易连接空间。 3)在java中wait和sleep方法的不同 通常会在电话面试中经常被问到的Java线程面试问题。最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。 4)用Java实现阻塞队列。 这是一个相对艰难的多线程面试问题,它能达到很多的目的。第一,它可以检测侯选者是否能实际的用Java线程写程序;第二,可以检测侯选者对并发场景的理解,并且你可以根据这个问很多问题。如果他用wait()和notify()方法来实现阻塞队列,你可以要求他用最新的Java 5中的并发类来再写一次。 5)用Java写代码来解决生产者——消费者问题。 与上面的问题很类似,但这个问题更经典,有些时候面试都会问下面的问题。在Java中怎么解决生产者——消费者问题,当然有很多解决方法,我已经分享了一种用阻塞队列实现的方法。有些时候他们甚至会问怎么实现哲学家进餐问题。 6)用Java编程一个会导致死锁的程序,你将怎么解决 这是我最喜欢的Java线程面试问题,因为即使死锁问题在写多线程并发程序时非常普遍,但是很多侯选者并不能写deadlock free code(无死锁代码),他们很挣扎。只要告诉他们,你有N个资源和N个线程,并且你需要所有的资源来完成一个操作。为了简单这里的n可以替换为2,越大的数据会使问题看起来更复杂。通过避免Java中的死锁来得到关于死锁的更多信息。 7) 什么是原子操作,Java中的原子操作是什么

黑马程序员Java教程:TCP协议服务端多线程技术

TCP协议服务端多线程技术 代码: UploadTask.java 1.import https://www.doczj.com/doc/ee14782500.html,.Socket; 2.import java.io.InputStream; 3.import java.io.FileOutputStream; 4.import java.io.File; 5.import java.io.OutputStream; 6. 7.public class UploadTask implements Runnable 8.{ 9. private Socket s; 10. 11. public UploadTask(Socket s){ 12. this.s = s; 13. } 14. 15. public void run(){ 16. 17. int count = 0; 18. 19. String ip = s.getInetAddress().getHostAddress(); 20. System.out.println(ip + "......connected"); 21. 22. try{ 23. InputStream in = s.getInputStream(); 24. 25. File dir = new File("c:\\pic"); 26. if(!dir.exists()){ 27. dir.mkdirs();

28. } 29. File file = new File(dir,ip + ".bmp"); 30. 31. //如果文件已经存在于服务端。 32. while(file.exists()){ 33. file = new File(dir,ip + "(" + (++count) + ").bmp"); 34. } 35. 36. FileOutputStream fos = new FileOutputStream(file); 37. 38. byte[] buf = new byte[1024]; 39. 40. int len = 0; 41. 42. while((len = in.read(buf)) != -1){ 43. fos.write(buf,0,len); 44. } 45. 46. OutputStream out = s.getOutputStream(); 47. 48. out.write("上传成功".getBytes()); 49. 50. fos.close(); 51. s.close(); 52. }catch(Exception e){ 53. e.printStackTrace(); 54. } 55. } 56.}

相关主题
文本预览
相关文档 最新文档