A. java 多线程是什么
进程是程序在处理机中的一次运行。一个进程既包括其所要执行的指令,也包括了执行指令所需的系统资源,不同进程所占用的系统资源相对独立。所以进程是重量级的任务,它们之间的通信和转换都需要操作系统付出较大的开销。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程自己基本上不拥有系统资源,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源。所以线程是轻量级的任务,它们之间的通信和转换只需要较小的系统开销。
Java支持多线程编程,因此用Java编写的应用程序可以同时执行多个任务。Java的多线程机制使用起来非常方便,用户只需关注程序细节的实现,而不用担心后台的多任务系统。
Java语言里,线程表现为线程类。Thread线程类封装了所有需要的线程操作控制。在设计程序时,必须很清晰地区分开线程对象和运行线程,可以将线程对象看作是运行线程的控制面板。在线程对象里有很多方法来控制一个线程是否运行,睡眠,挂起或停止。线程类是控制线程行为的唯一的手段。一旦一个Java程序启动后,就已经有一个线程在运行。可通过调用Thread.currentThread方法来查看当前运行的是哪一个线程。
B. 《Java线程与并发编程实践》pdf下载在线阅读全文,求百度网盘云资源
《Java线程与并发编程实践》网络网盘pdf最新全集下载:
链接: https://pan..com/s/1zebgAWKpIEWptv9zB_Y2GA
C. 什么是JAVA的多线程
简单,先回答什么是线程:即程序的执行路径,再回答多线程:多线程就是一个程序中有多条不同的执行路径
JAVA多线程的优点:可以并发的执行多项任务,比如说你浏览网页的同时还可以听歌
D. java 多线程是什么一个处理器怎么同时处理多个程序
进程是程序在处理机中的一次运行。一个进程既包括其所要执行的指令,也包括了执行指令所需的系统资源,不同进程所占用的系统资源相对独立。所以进程是重量级的任务,它们之间的通信和转换都需要操作系统付出较大的开销。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程自己基本上不拥有系统资源,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源。所以线程是轻量级的任务,它们之间的通信和转换只需要较小的系统开销。
Java支持多线程编程,因此用Java编写的应用程序可以同时执行多个任务。Java的多线程机制使用起来非常方便,用户只需关注程序细节的实现,而不用担心后台的多任务系统。
Java语言里,线程表现为线程类。Thread线程类封装了所有需要的线程操作控制。在设计程序时,必须很清晰地区分开线程对象和运行线程,可以将线程对象看作是运行线程的控制面板。在线程对象里有很多方法来控制一个线程是否运行,睡眠,挂起或停止。线程类是控制线程行为的唯一的手段。一旦一个Java程序启动后,就已经有一个线程在运行。可通过调用Thread.currentThread方法来查看当前运行的是哪一个线程。
class ThreadTest{
public static void main(String args[]){
Thread t = Thread.currentThread();
t.setName("单线程"); //对线程取名为"单线程"
t.setPriority(8);
//设置线程优先级为8,最高为10,最低为1,默认为5
System.out.println("The running thread: " + t);
// 显示线程信息
try{
for(int i=0;i<3;i++){
System.out.println("Sleep time " + i);
Thread.sleep(100); // 睡眠100毫秒
}
}catch(InterruptedException e){// 捕获异常
System.out.println("thread has wrong");
}
}
}
多线程的实现方法
继承Thread类
可通过继承Thread类并重写其中的run()方法来定义线程体以实现线程的具体行为,然后创建该子类的对象以创建线程。
在继承Thread类的子类ThreadSubclassName中重写run()方法来定义线程体的一般格式为:
public class ThreadSubclassName extends Thread{
public ThreadSubclassName(){
..... // 编写子类的构造方法,可缺省
}
public void run(){
..... // 编写自己的线程代码
}
}
用定义的线程子类ThreadSubclassName创建线程对象的一般格式为:
ThreadSubclassName ThreadObject =
new ThreadSubclassName();
然后,就可启动该线程对象表示的线程:
ThreadObject.start(); //启动线程
应用继承类Thread的方法实现多线程的程序。本程序创建了三个单独的线程,它们分别打印自己的“Hello World!”。
class ThreadDemo extends Thread{
private String whoami;
private int delay;
public ThreadDemo(String s,int d){
whoami=s;
delay=d;
}
public void run(){
try{
sleep(delay);
}catch(InterruptedException e){ }
System.out.println("Hello World!" + whoami
+ " " + delay);
}
}
public class MultiThread{
public static void main(String args[]){
ThreadDemo t1,t2,t3;
t1 = new ThreadDemo("Thread1",
(int)(Math.random()*2000));
t2 = new ThreadDemo("Thread2",
(int)(Math.random()*2000));
t3 = new ThreadDemo("Thread3",
(int)(Math.random()*2000));
t1.start();
t2.start();
t3.start();
}
}
实现Runnable接口
编写多线程程序的另一种的方法是实现Runnable接口。在一个类中实现Runnable接口(以后称实现Runnable接口的类为Runnable类),并在该类中定义run()方法,然后用带有Runnable参数的Thread类构造方法创建线程。
创建线程对象可用下面的两个步骤来完成:
(1)生成Runnable类ClassName的对象
ClassName RunnableObject = new ClassName();
(2)用带有Runnable参数的Thread类构造方法创建线程对象。新创建的线程的指针将指向Runnable类的实例。用该Runnable类的实例为线程提供 run()方法---线程体。
Thread ThreadObject = new Thread(RunnableObject);
然后,就可启动线程对象ThreadObject表示的线程:
ThreadObject.start();
在Thread类中带有Runnable接口的构造方法有:
public Thread(Runnable target);
public Thread(Runnable target, String name);
public Thread(String name);
public Thread(ThreadGroup group,Runnable target);
public Thread(ThreadGroup group,Runnable target,
String name);
其中,参数Runnable target表示该线程执行时运行target的run()方法,String name以指定名字构造线程,ThreadGroup group表示创建线程组。
用Runnable接口实现的多线程。
class TwoThread implements Runnable{
TwoThread(){
Thread t1 = Thread.currentThread();
t1.setName("第一主线程");
System.out.println("正在运行的线程: " + t1);
Thread t2 = new Thread(this,"第二线程");
System.out.println("创建第二线程");
t2.start();
try{
System.out.println("第一线程休眠");
Thread.sleep(3000);
}catch(InterruptedException e){
System.out.println("第一线程有错");
}
System.out.println("第一线程退出");
}
public void run(){
try{
for(int i = 0;i < 5;i++){
System.out.println(“第二线程的休眠时间:”
+ i);
Thread.sleep(1000);
}
}catch(InterruptedException e){
System.out.println("线程有错");
}
System.out.println("第二线程退出");
}
public static void main(String args[]){
new TwoThread();
}
}
程序运行结果如下:
正在运行的线程: Thread[第一主线程,5,main
创建第二线程
第一线程休眠
第二线程的休眠时间:0
第二线程的休眠时间:1
第二线程的休眠时间:2
第一线程退出
第二线程的休眠时间:3
第二线程的休眠时间:4
第二线程退出
至于一个处理器同时处理多个程序,其实不是同时运行多个程序的,简单的说,如果是单核的CPU,在运行多个程序的时候其实是每个程序轮流占用CPU的,只是每个程序占用的时间很短,所以我们人为的感觉是“同时”运行多个程序。
E. java 多线程
public class Test {
boolean ready_c = false;
boolean ready_a = false;
boolean ready_b = false;
Object obj = new Object();
/**
* @param args
*/
public static void main(String[] args) {
Object a = new Object();
new Test();
}
public Test() {
new A().start();
new B().start();
new C().start();
}
class A extends Thread {
public void run() {
System.out.println("Thread A started...");
try {
synchronized(obj) {
while(!ready_c)obj.wait();
System.out.println("Thread A ended...");
ready_a = true;
obj.notifyAll();
}
}catch(Exception e) {
}
}
}
class B extends Thread {
public void run() {
System.out.println("Thread B started...");
try {
synchronized(obj) {
while(!ready_c)obj.wait();
System.out.println("Thread B ended...");
ready_a = true;
obj.notifyAll();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
class C extends Thread {
public void run() {
try {
sleep(5000);
synchronized(obj) {
ready_c = true;
obj.notifyAll();
while(!ready_a&&!ready_b)obj.wait();
System.out.println("Thread C ended...");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
F. 推荐几本非常棒的Java多线程编程书籍
Unix_Linux_多线程编程.pdf或者在网络或google上搜索“unix多线程编程”或“multi-threadprogramming",会有很多参考资料的。基本上了解线程创建、线程执行的function、及线程之间信息交互(全局变量设置)等就可以了,相比多进程之间通信必须要用到socket/sharedmemory等等还是简单一些的。如果编写大型一点的程序,建议你不要频繁的创建和删除线程,建个threadpool更高效也运行更稳定一点,网上搜搜threadpool相关的资料研究一下吧。
G. 在Java 中多线程的实现方法有哪些,如何使用
Java多线程的创建及启动
Java中线程的创建常见有如三种基本形式
1.继承Thread类,重写该类的run()方法。
复制代码
1 class MyThread extends Thread {
2
3 private int i = 0;
4
5 @Override
6 public void run() {
7 for (i = 0; i < 100; i++) {
8 System.out.println(Thread.currentThread().getName() + " " + i);
9 }
10 }
11 }
复制代码
复制代码
1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 for (int i = 0; i < 100; i++) {
5 System.out.println(Thread.currentThread().getName() + " " + i);
6 if (i == 30) {
7 Thread myThread1 = new MyThread(); // 创建一个新的线程 myThread1 此线程进入新建状态
8 Thread myThread2 = new MyThread(); // 创建一个新的线程 myThread2 此线程进入新建状态
9 myThread1.start(); // 调用start()方法使得线程进入就绪状态
10 myThread2.start(); // 调用start()方法使得线程进入就绪状态
11 }
12 }
13 }
14 }
复制代码
如上所示,继承Thread类,通过重写run()方法定义了一个新的线程类MyThread,其中run()方法的方法体代表了线程需要完成的任务,称之为线程执行体。当创建此线程类对象时一个新的线程得以创建,并进入到线程新建状态。通过调用线程对象引用的start()方法,使得该线程进入到就绪状态,此时此线程并不一定会马上得以执行,这取决于CPU调度时机。
2.实现Runnable接口,并重写该接口的run()方法,该run()方法同样是线程执行体,创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。
复制代码
1 class MyRunnable implements Runnable {
2 private int i = 0;
3
4 @Override
5 public void run() {
6 for (i = 0; i < 100; i++) {
7 System.out.println(Thread.currentThread().getName() + " " + i);
8 }
9 }
10 }
复制代码
复制代码
1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 for (int i = 0; i < 100; i++) {
5 System.out.println(Thread.currentThread().getName() + " " + i);
6 if (i == 30) {
7 Runnable myRunnable = new MyRunnable(); // 创建一个Runnable实现类的对象
8 Thread thread1 = new Thread(myRunnable); // 将myRunnable作为Thread target创建新的线程
9 Thread thread2 = new Thread(myRunnable);
10 thread1.start(); // 调用start()方法使得线程进入就绪状态
11 thread2.start();
12 }
13 }
14 }
15 }
复制代码
相信以上两种创建新线程的方式大家都很熟悉了,那么Thread和Runnable之间到底是什么关系呢?我们首先来看一下下面这个例子。
复制代码
1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 for (int i = 0; i < 100; i++) {
5 System.out.println(Thread.currentThread().getName() + " " + i);
6 if (i == 30) {
7 Runnable myRunnable = new MyRunnable();
8 Thread thread = new MyThread(myRunnable);
9 thread.start();
10 }
11 }
12 }
13 }
14
15 class MyRunnable implements Runnable {
16 private int i = 0;
17
18 @Override
19 public void run() {
20 System.out.println("in MyRunnable run");
21 for (i = 0; i < 100; i++) {
22 System.out.println(Thread.currentThread().getName() + " " + i);
23 }
24 }
25 }
26
27 class MyThread extends Thread {
28
29 private int i = 0;
30
31 public MyThread(Runnable runnable){
32 super(runnable);
33 }
34
35 @Override
36 public void run() {
37 System.out.println("in MyThread run");
38 for (i = 0; i < 100; i++) {
39 System.out.println(Thread.currentThread().getName() + " " + i);
40 }
41 }
42 }
复制代码
同样的,与实现Runnable接口创建线程方式相似,不同的地方在于
1 Thread thread = new MyThread(myRunnable);
那么这种方式可以顺利创建出一个新的线程么?答案是肯定的。至于此时的线程执行体到底是MyRunnable接口中的run()方法还是MyThread类中的run()方法呢?通过输出我们知道线程执行体是MyThread类中的run()方法。其实原因很简单,因为Thread类本身也是实现了Runnable接口,而run()方法最先是在Runnable接口中定义的方法。
1 public interface Runnable {
2
3 public abstract void run();
4
5 }
我们看一下Thread类中对Runnable接口中run()方法的实现:
复制代码
@Override
public void run() {
if (target != null) {
target.run();
}
}
复制代码
也就是说,当执行到Thread类中的run()方法时,会首先判断target是否存在,存在则执行target中的run()方法,也就是实现了Runnable接口并重写了run()方法的类中的run()方法。但是上述给到的列子中,由于多态的存在,根本就没有执行到Thread类中的run()方法,而是直接先执行了运行时类型即MyThread类中的run()方法。
3.使用Callable和Future接口创建线程。具体是创建Callable接口的实现类,并实现clall()方法。并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。
看着好像有点复杂,直接来看一个例子就清晰了。
复制代码
1 public class ThreadTest {
2
3 public static void main(String[] args) {
4
5 Callable<Integer> myCallable = new MyCallable(); // 创建MyCallable对象
6 FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); //使用FutureTask来包装MyCallable对象
7
8 for (int i = 0; i < 100; i++) {
9 System.out.println(Thread.currentThread().getName() + " " + i);
10 if (i == 30) {
11 Thread thread = new Thread(ft); //FutureTask对象作为Thread对象的target创建新的线程
12 thread.start(); //线程进入到就绪状态
13 }
14 }
15
16 System.out.println("主线程for循环执行完毕..");
17
18 try {
19 int sum = ft.get(); //取得新创建的新线程中的call()方法返回的结果
20 System.out.println("sum = " + sum);
21 } catch (InterruptedException e) {
22 e.printStackTrace();
23 } catch (ExecutionException e) {
24 e.printStackTrace();
25 }
26
27 }
28 }
29
30
31 class MyCallable implements Callable<Integer> {
32 private int i = 0;
33
34 // 与run()方法不同的是,call()方法具有返回值
35 @Override
36 public Integer call() {
37 int sum = 0;
38 for (; i < 100; i++) {
39 System.out.println(Thread.currentThread().getName() + " " + i);
40 sum += i;
41 }
42 return sum;
43 }
44
45 }
复制代码
首先,我们发现,在实现Callable接口中,此时不再是run()方法了,而是call()方法,此call()方法作为线程执行体,同时还具有返回值!在创建新的线程时,是通过FutureTask来包装MyCallable对象,同时作为了Thread对象的target。那么看下FutureTask类的定义:
1 public class FutureTask<V> implements RunnableFuture<V> {
2
3 //....
4
5 }
1 public interface RunnableFuture<V> extends Runnable, Future<V> {
2
3 void run();
4
5 }
于是,我们发现FutureTask类实际上是同时实现了Runnable和Future接口,由此才使得其具有Future和Runnable双重特性。通过Runnable特性,可以作为Thread对象的target,而Future特性,使得其可以取得新创建线程中的call()方法的返回值。
执行下此程序,我们发现sum = 4950永远都是最后输出的。而“主线程for循环执行完毕..”则很可能是在子线程循环中间输出。由CPU的线程调度机制,我们知道,“主线程for循环执行完毕..”的输出时机是没有任何问题的,那么为什么sum =4950会永远最后输出呢?
原因在于通过ft.get()方法获取子线程call()方法的返回值时,当子线程此方法还未执行完毕,ft.get()方法会一直阻塞,直到call()方法执行完毕才能取到返回值。
上述主要讲解了三种常见的线程创建方式,对于线程的启动而言,都是调用线程对象的start()方法,需要特别注意的是:不能对同一线程对象两次调用start()方法。
你好,本题已解答,如果满意
请点右下角“采纳答案”。
H. 如何用Java编写多线程
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
对于直接继承Thread的类来说,代码大致框架是:
?
123456789101112 class 类名 extends Thread{ 方法1; 方法2; … public void run(){ // other code… } 属性1; 属性2; … }
先看一个简单的例子:
?
/** * @author Rollen-Holt 继承Thread类,直接调用run方法 * */class hello extends Thread { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "运行 " + i); } } public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.run(); h2.run(); } private String name; }
【运行结果】:
A运行 0
A运行 1
A运行 2
A运行 3
A运行 4
B运行 0
B运行 1
B运行 2
B运行 3
B运行 4
我们会发现这些都是顺序执行的,说明我们的调用方法不对,应该调用的是start()方法。
当我们把上面的主函数修改为如下所示的时候:
?
123456 public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.start(); h2.start(); }
然后运行程序,输出的可能的结果如下:
A运行 0
B运行 0
B运行 1
B运行 2
B运行 3
B运行 4
A运行 1
A运行 2
A运行 3
A运行 4
因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的,呵呵。
注意:虽然我们在这里调用的是start()方法,但是实际上调用的还是run()方法的主体。
那么:为什么我们不能直接调用run()方法呢?
我的理解是:线程的运行需要本地操作系统的支持。
如果你查看start的源代码的时候,会发现:
?
1234567891011121314151617 public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0 || this != me) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop); } } private native void start0();
注意我用红色加粗的那一条语句,说明此处调用的是start0()。并且这个这个方法用了native关键字,次关键字表示调用本地操作系统的函数。因为多线程的实现需要本地操作系统的支持。
但是start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。
通过实现Runnable接口:
大致框架是:
?
123456789101112 class 类名 implements Runnable{ 方法1; 方法2; … public void run(){ // other code… } 属性1; 属性2; … }
来先看一个小例子吧:
?
2930 /** * @author Rollen-Holt 实现Runnable接口 * */class hello implements Runnable { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "运行 " + i); } } public static void main(String[] args) { hello h1=new hello("线程A"); Thread demo= new Thread(h1); hello h2=new hello("线程B"); Thread demo1=new Thread(h2); demo.start(); demo1.start(); } private String name; }
【可能的运行结果】:
线程A运行 0
线程B运行 0
线程B运行 1
线程B运行 2
线程B运行 3
线程B运行 4
线程A运行 1
线程A运行 2
线程A运行 3
线程A运行 4
关于选择继承Thread还是实现Runnable接口?
其实Thread也是实现Runnable接口的:
?
12345678 class Thread implements Runnable { //… public void run() { if (target != null) { target.run(); } } }
其实Thread中的run方法调用的是Runnable接口的run方法。不知道大家发现没有,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。关于代理模式,我曾经写过一个小例子呵呵,大家有兴趣的话可以看一下:http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144847.html
Thread和Runnable的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
?
/** * @author Rollen-Holt 继承Thread类,不能资源共享 * */class hello extends Thread { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello h1 = new hello(); hello h2 = new hello(); hello h3 = new hello(); h1.start(); h2.start(); h3.start(); } private int count = 5; }
【运行结果】:
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。
我们换为Runnable接口:
?
12345678910111213141516171819 /** * @author Rollen-Holt 继承Thread类,不能资源共享 * */class hello implements Runnable { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello he=new hello(); new Thread(he).start(); } private int count = 5; }
【运行结果】:
count= 5
count= 4
count= 3
count= 2
count= 1
总结一下吧:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
所以,本人建议大家劲量实现接口。
?
I. 如何使用Java编写多线程程序(1)
一、简介1、什么是线程要说线程,就必须先说说进程,进程就是程序的运行时的一个实例。线程呢可以看作单独地占有CPU时间来执行相应的代码的。对早期的计算机(如DOS)而言,线程既是进程,进程既是进程,因为她是单线程的。当然一个程序可以是多线程的,多线程的各个线程看上去像是并行地独自完成各自的工作,就像一台一台计算机上运行着多个处理机一样。在多处理机计算机上实现多线程时,它们确实可以并行工作,而且采用适当的分时策略可以大大提高程序运行的效率。但是二者还是有较大的不同的,线程是共享地址空间的,也就是说多线程可以同时读取相同的地址空间,并且利用这个空间进行交换数据。 2、为什么要使用线程为什么要使用多线程呢?学过《计算机体系结构》的人都知道。将顺序执行程序和采用多线程并行执行程序相比,效率是可以大大地提高的。比如,有五个线程thread1, thread2, thread3, thread4, thread5,所耗的CPU时间分别为4,5,1,2,7。(假设CPU轮换周期为4个CPU时间,而且线程之间是彼此独立的)顺序执行需要花费1Array个CPU时间,而并行需要的时间肯定少于1Array个CPU时间,至于具体多少时间要看那些线程是可以同时执行的。这是在非常小规模的情况下,要是面对大规模的进程之间的交互的话,效率可以表现得更高。 3、java中是如何实现多线程的与其他语言不一样的是,线程的观念在java是语言中是重要的,根深蒂固的,因为在java语言中的线程系统是java语言自建的, java中有专门的支持多线程的API库,所以你可以以最快的速度写一个支持线程的程序。在使用java创建线程的时候,你可以生成一个Thread类或者他的子类对象,并给这个对象发送start()消息(程序可以向任何一个派生自 Runnable 接口的类对象发送 start() 消息的),这样一来程序会一直执行,直到run返回为止,此时该线程就死掉了。在java语言中,线程有如下特点:§ 在一个程序中而言,主线程的执行位置就是main。而其他线程执行的位置,程序员是可以自定义的。值得注意的是对Applet也是一样。 § 每个线程执行其代码的方式都是一次顺序执行的。 § 一个线程执行其代码是与其他线程独立开来的。如果诸线程之间又相互协作的话,就必须采用一定的交互机制。 § 前面已经说过,线程是共享地址空间的,如果控制不当,这里很有可能出现死锁。 各线程之间是相互独立的,那么本地变量对一个线程而言就是完全独立,私有的。所以呢,线程执行时,每个线程都有各自的本地变量拷贝。对象变量(instance variable)在线程之间是可以共享的,这也就是为什么在java中共享数据对象是如此的好用,但是java线程不能够武断地访问对象变量:他们是需要访问数据对象的权限的。二、准备知识 在分析这个例子之前,然我们先看看关于线程的几个概念,上锁,信号量,和java所提供的API。 上锁对于大多数的程序而言,他们都需要线程之间相互的通讯来完成整个线程的生命周期,二实现线程之间同步的最简单的办法就是上锁。为了防止相互关联的两个线程之间错误地访问共享资源,线程需要在访问资源的时候上锁和解锁,对于锁而言,有读锁,写锁和读写锁等不同的同步策略。在java中,所有的对象都有锁;线程只需要使用synchronized关键字就可以获得锁。在任一时刻对于给定的类的实例,方法或同步的代码块只能被一个线程执行。这是因为代码在执行之前要求获得对象的锁。 信号量通常情况下,多个线程所访问为数不多的资源,那怎么控制呢?一个比较非常经典而起非常简单的办法就是采用信号量机制。信号量机制的含义就是定义一个信号量,也就是说能够提供的连接数;当有一个线程占用了一个连接时,信号量就减一;当一个线程是放了连接时,信号量就加一。
J. 求《Java多线程编程核心技术(高洪岩0》全文免费下载百度网盘资源,谢谢~
《Java多线程编程核心技术(高洪岩0》网络网盘pdf最新全集下载:
链接: https://pan..com/s/1GzMYjd5gdh4DXDUYthmM9Q