java 线程基本用法

java中的多线程

一、      java 线程基本介绍

1、进程与线程的区别

进程是指一个内存中运行的应用程序,每个进程都有一块独立的内存空间,一个进程包含一到多个线程。

每个线程都有他所属的进程,每个线程也就是该进程的一条执行路径,线程之间是高频率快速轮换执行的,‘同时’执行只是给人的感觉。

2、Java当中线程一般有5中状态

创建状态:生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。

就绪状态:当调用了线程的start方法,线程就进入就绪状态,调用start方法后线程不是立即执行的,只是开始排队等待执行了,具体什么时候执行得看CPU心情,当线程从等待或者休眠状态回来之后也是进入到就绪状态。

运行状态:开始运行run()函数的代码,这时候就是运行状态啦。

阻塞状态:线程正在运行的时候被暂停就是进入到阻塞状态,sleep,suspend,wait都可以使线程进入阻塞状态。

死亡状态:run()方法运行结束或者调用了线程的stop方法后,该线程就会死亡,对于已经死亡的线程无法使用start方法使其进入就绪状态。

 

在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。

对于直接继承Thread的类来说,代码大致框架是:

 1 class 类名 extends Thread{
 2
 3 方法1;
 4
 5 方法2;
 6
 7 …
 8
 9 public void run(){
10
11 // other code…
12
13 }
14
15 属性1;
16
17 属性2;
18
19 …
20
21
22
23 }


先看一个简单的例子:

 1 package com.hxw.Threads;
 2
 3
 4
 5 class ThreadTest {
 6
 7
 8
 9     /**
10
11      * 观察直接调用run()和用start()启动一个线程的差别
12
13      * @author HaiCheng
14
15      * @param args
16
17      * @throws Exception
18
19      */
20
21     public static void main(String[] args){
22
23        Thread r=new ThreadDemo("直接调用run执行");
24
25        r.run();
26
27         Thread t1=new ThreadDemo("线程一");
28
29         t1.start();
30
31         Thread t2=new ThreadDemo("线程二");
32
33         t2.start();
34
35         for(int i=0;i<10;i++){
36
37           System.out.println("主线程执行------>"+i);
38
39         }
40
41     }
42
43
44
45     public static class ThreadDemo extends Thread{
46
47        private String ThreadName;
48
49        public ThreadDemo(String s){
50
51           this.ThreadName=s;
52
53        }
54
55         @Override
56
57         public void run() {
58
59             for (int i = 0; i < 10; i++) {
60
61                 System.out.println(this.getThreadName()+"执行------>"+i);
62
63             }
64
65         }
66
67       public String getThreadName() {
68
69          return ThreadName;
70
71       }
72
73     }
74
75 }

run和start的区别

1) start:

用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

2) run:

run方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

通过实现Runnable接口:

大致框架是:

 1 class 类名 implements Runnable{
 2
 3 方法1;
 4
 5 方法2;
 6
 7 …
 8
 9 public void run(){
10
11 // other code…
12
13 }
14
15 属性1;
16
17 属性2;
18
19 …
20
21
22
23 }

来先看一个小例子吧:

 1 /**
 2
 3  * @author Rollen-Holt 实现Runnable接口
 4
 5  * */
 6
 7 class hello implements Runnable {
 8
 9
10
11     public hello() {
12
13
14
15     }
16
17
18
19     public hello(String name) {
20
21         this.name = name;
22
23     }
24
25
26
27     public void run() {
28
29         for (int i = 0; i < 5; i++) {
30
31             System.out.println(name + "运行     " + i);
32
33         }
34
35     }
36
37
38
39     public static void main(String[] args) {
40
41         hello h1=new hello("线程A");
42
43         Thread demo= new Thread(h1);
44
45         hello h2=new hello("线程B");
46
47         Thread demo1=new Thread(h2);
48
49         demo.start();
50
51         demo1.start();
52
53     }
54
55
56
57     private String name;
58
59 }

【可能的运行结果】:

线程A运行     0

线程B运行     0

线程B运行     1

线程B运行     2

线程B运行     3

线程B运行     4

线程A运行     1

线程A运行     2

线程A运行     3

线程A运行     4

关于选择继承Thread还是实现Runnable接口?

其实Thread也是实现Runnable接口的

 1 class Thread implements Runnable {
 2
 3     //…
 4
 5 public void run() {
 6
 7         if (target != null) {
 8
 9              target.run();
10
11         }
12
13         }
14
15 }

ThreadRunnable的区别:

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

 1 /**
 2
 3  * @author Rollen-Holt 继承Thread类,不能资源共享
 4
 5  * */
 6
 7 class hello extends Thread {
 8
 9     public void run() {
10
11         for (int i = 0; i < 7; i++) {
12
13             if (count > 0) {
14
15                 System.out.println("count= " + count--);
16
17             }
18
19         }
20
21     }
22
23
24
25     public static void main(String[] args) {
26
27         hello h1 = new hello();
28
29         hello h2 = new hello();
30
31         hello h3 = new hello();
32
33         h1.start();
34
35         h2.start();
36
37         h3.start();
38
39     }
40
41
42
43     private int count = 5;
44
45 }

【运行结果】:

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接口

 1 class MyThread implements Runnable{
 2
 3
 4
 5     private int ticket = 5;  //5张票
 6
 7
 8
 9     public void run() {
10
11         for (int i=0; i<=20; i++) {
12
13             if (this.ticket > 0) {
14
15                 System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
16
17             }
18
19         }
20
21     }
22
23 }
24
25 public class lzwCode {
26
27
28
29     public static void main(String [] args) {
30
31         MyThread my = new MyThread();
32
33         new Thread(my, "1号窗口").start();
34
35         new Thread(my, "2号窗口").start();
36
37         new Thread(my, "3号窗口").start();
38
39     }
40
41 }

【运行结果】:

count= 5

count= 4

count= 3

count= 2

count= 1

 

总结一下吧:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

所以,本人建议大家尽量实现接口。

 1 /**
 2
 3  * @author Rollen-Holt
 4
 5  * 取得线程的名称
 6
 7  * */
 8
 9 class hello implements Runnable {
10
11     public void run() {
12
13         for (int i = 0; i < 3; i++) {
14
15             System.out.println(Thread.currentThread().getName());
16
17         }
18
19     }
20
21
22
23     public static void main(String[] args) {
24
25         hello he = new hello();
26
27         new Thread(he,"A").start();
28
29         new Thread(he,"B").start();
30
31         new Thread(he).start();
32
33     }
34
35 }

【运行结果】:

A

A

A

B

B

B

Thread-0

Thread-0

Thread-0

说明如果我们没有指定名字的话,系统自动提供名字。

提醒一下大家:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。

 

java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实际在就是在操作系统中启动了一个进程。

二、       线程常用方法解析

  1. 1.        判断线程是否启动:

方法解析:在这里提一下上面的

currentThread() 方法,返回对当前正在执行的线程对象的引用。

isAlive(),测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

 1 package com.hxw.Threads;
 2
 3
 4
 5 /**
 6
 7  * @author Rollen-Holt 判断线程是否启动
 8
 9  * */
10
11 class hello implements Runnable {
12
13     public void run() {
14
15         for (int i = 0; i < 3; i++) {
16
17             System.out.println(Thread.currentThread().getName());
18
19         }
20
21     }
22
23
24
25     public static void main(String[] args) {
26
27         hello he = new hello();
28
29         Thread demo = new Thread(he);
30
31         System.out.println("线程启动之前---》" + demo.isAlive());
32
33         demo.start();
34
35         System.out.println("线程启动之后---》" + demo.isAlive());
36
37         System.out.println("线程启动之后后 ---》" + demo.isAlive());
38
39         System.out.println("线程启动之后后 ---》" + demo.isAlive());
40
41         System.out.println("线程启动之后后 ---》" + demo.isAlive());
42
43         System.out.println("线程启动之后后 ---》" + demo.isAlive());
44
45         System.out.println("线程启动之后后 ---》" + demo.isAlive());
46
47         System.out.println("线程启动之后后 ---》" + demo.isAlive());
48
49         System.out.println("线程启动之后后 ---》" + demo.isAlive());
50
51
52
53     }
54
55 }

【运行结果】

线程启动之前---》false

线程启动之后---》true

线程启动之后后 ---》true

Thread-0

线程启动之后后 ---》true

线程启动之后后 ---》true

Thread-0

线程启动之后后 ---》true

Thread-0

线程启动之后后 ---》true

线程启动之后后 ---》false

线程启动之后后 ---》false

从上面的例子来看:确实是有主线程和子线程在运行的,而且主线程也有可能在子线程结束之前结束。并且子线程不受影响,不会因为主线程的结束而结束。这个叫非守护线程。

上面的例子也表示出了在run方法执行完成后,线程就死亡了,只是由于主线程和子线程之间同步问题,如果想原文的那样在demo.start()后只打印一个alive()是有问题的。

  1. 线程的强制执行:thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法即A.jion(),直到线程A执行完毕后,才会继续执行线程B。

t.join();      //使调用线程 t 在此之前执行完毕。

t.join(1000);  //等待 t 线程,等待时间是1000毫秒

 1 /**
 2
 3      * @author Rollen-Holt 线程的强制执行
 4
 5      * */
 6
 7     class hello implements Runnable {
 8
 9         public void run() {
10
11             for (int i = 0; i < 3; i++) {
12
13                 System.out.println(Thread.currentThread().getName());
14
15             }
16
17         }
18
19
20
21         public static void main(String[] args) {
22
23             hello he = new hello();
24
25             Thread demo = new Thread(he,"线程");
26
27             demo.start();
28
29             for(int i=0;i<50;++i){
30
31                 if(i>10){
32
33                     try{
34
35                         demo.join();  //强制执行demo()
36
37                     }catch (Exception e) {
38
39                         e.printStackTrace();
40
41                     }
42
43                 }
44
45                 System.out.println("main 线程执行-->"+i);
46
47             }
48
49         }
50
51     }

【运行的结果】:

main 线程执行-->0

main 线程执行-->1

main 线程执行-->2

main 线程执行-->3

main 线程执行-->4

main 线程执行-->5

main 线程执行-->6

main 线程执行-->7

main 线程执行-->8

main 线程执行-->9

main 线程执行-->10

线程

线程

线程

main 线程执行-->11

main 线程执行-->12

main 线程执行-->13

...

  1. 3.       线程的休眠:sleep() 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),

sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

 1 package com.hxw.Threads;
 2
 3
 4
 5 import java.text.SimpleDateFormat;
 6
 7
 8
 9 /**
10
11  * @author Rollen-Holt 线程的休眠
12
13  * */
14
15 class hello implements Runnable {
16
17     public void run() {
18
19         for (int i = 0; i < 3; i++) {
20
21             try {
22
23                 Thread.sleep(2000);
24
25             } catch (Exception e) {
26
27                 e.printStackTrace();
28
29             }
30
31             System.out.println(Thread.currentThread().getName() + i+"   "+(new SimpleDateFormat("yyyy-MM-dd   hh:mm:ss").format(new java.util.Date())));
32
33         }
34
35     }
36
37
38
39     public static void main(String[] args) {
40
41         hello he = new hello();
42
43         Thread demo = new Thread(he, "线程");
44
45         demo.start();
46
47     }
48
49 }
50
51  

【运行结果】:(结果每隔2s输出一个)

线程0   2014-08-16   06:06:21

线程1   2014-08-16   06:06:23

线程2   2014-08-16   06:06:25

  1. 4.       线程的优先级:

与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。

线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先级为5,主线程的优先级也是5。

在一个线程中开启另外一个新线程,则新开线程称为该线程的子线程,子线程初始优先级与父线程相同。
可以用下面方法设置和返回线程的优先级。
public final void setPriority(int newPriority) 设置线程的优先级。
public final int getPriority() 返回线程的优先级。
 newPriority为线程的优先级,其取值为1到10之间的整数,也可以使用Thread类定义的常量来设置线程的优先级,这些常量分别为:Thread.MIN_PRIORITY、Thread.NORM_PRIORITY、Thread.MAX_PRIORITY,它们分别对应于线程优先级的1、5和10,数值越大优先级越高。当创建Java线程时,如果没有指定它的优先级,则它从创建该线程那里继承优先级。

 

 1 /**
 2
 3  * @author Rollen-Holt 线程的优先级
 4
 5  * */
 6
 7 class hello implements Runnable {
 8
 9     public void run() {
10
11         for(int i=0;i<5;++i){
12
13             System.out.println(Thread.currentThread().getName()+"运行"+i);
14
15         }
16
17     }
18
19
20
21     public static void main(String[] args) {
22
23         Thread h1=new Thread(new hello(),"A");
24
25         Thread h2=new Thread(new hello(),"B");
26
27         Thread h3=new Thread(new hello(),"C");
28
29         h1.setPriority(8);
30
31         h2.setPriority(2);
32
33         h3.setPriority(6);
34
35         h1.start();
36
37         h2.start();
38
39         h3.start();
40
41
42
43     }
44
45 }

【运行结果】:

A运行0

A运行1

A运行2

A运行3

A运行4

B运行0

C运行0

C运行1

C运行2

C运行3

C运行4

B运行1

B运行2

B运行3

B运行4

  1. 5.       
    线程的礼让: yield()

通过调用yield方法,线程可能自动的转发控制权给其他等待的线程,一般情况,在等待其他具有相同优先级的线程产生的某个结果是,线程会转让控制权。考虑如下情形,多线程情况下,有一个可读写文件由多个线程来读写操作,多线程情况下,为了保证数据一致性,在读写访问时都将锁住这个文件,读写线程可能都运行在相同的优先级,现在拥有文件锁的线程可能会周期性的将控制权转让给另一个与之竞争的线程。

需要注意的是,yield()方法对JVM来说是“提示”,而不是强制要求,也没有结束。JVM无法保证线程调度的确定性,这一点我们会在下面的例子展示出来,除此之外也不能确定这个提示是让更低级的线程获得控制权还是同级的线程获得控制权,尽管大多数情况下是同级线程获得控制权的。这个方法比较不稳定,一般不常用。它所表达的意思口语化一点就是:“我急获得了足够的CPU时间,想让其他线程有机会运行,我将在一段时间后运行剩余的代码”,这与sleep方法不一样,sleep的意思是:“在n毫秒的时间内我不想运行,就算没有其他线程想运行,也别让我运行”。

 1 package com.hxw.Threads;
 2
 3
 4
 5 /**
 6
 7  * @author Rollen-Holt 线程的优先级
 8
 9  * */
10
11 class hello2 implements Runnable {
12
13     synchronized  public void run() {
14
15         for(int i=0;i<12;++i){
16
17             System.out.println(Thread.currentThread().getName()+"运行"+i);
18
19             if(i==3){
20
21                 Thread.currentThread().yield();
22
23                 System.out.println(Thread.currentThread().getName()+"将自己的线程礼让出来了");
24
25             }
26
27         }
28
29     }
30
31
32
33     public static void main(String[] args) {
34
35         Thread h1=new Thread(new hello2(),"A");
36
37         Thread h2=new Thread(new hello2(),"B");
38
39         h1.start();
40
41         h2.start();
42
43
44
45     }
46
47 }

A运行0

B运行0

A运行1

B运行1

A运行2

B运行2

A运行3

A将自己的线程礼让出来了

A运行4

A运行5

A运行6

A运行7

A运行8

A运行9

A运行10

A运行11

A运行12

B运行3

B将自己的线程礼让出来了

B运行4

B运行5

B运行6

B运行7

B运行8

B运行9

B运行10

B运行11

B运行12

相信读者看完上面的结果想“呵呵!”了,A真不客气,都说将自己的线程礼让出来了还愣是把自己运行完了才把控制权交给B,这就是yiel()方法的“提示”转让。当然有些时候还会准确的让出控制权的。

  1. 6.       线程的中断(打扰):

中断的原理: Java中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。这好比是家里的父母叮嘱在外的子女要注意身体,但子女是否注意身体,怎么注意身体则完全取决于自己。

Java中断模型也是这么简单,每个线程对象里都有一个boolean类型的标识(不一定就要是Thread类的字段,实际上也的确不是,这几个方法最终都是通过native方法来完成的),代表着是否有中断请求(该请求可以来自所有线程,包括被中断的线程本身)。例如,当线程t1想中断线程t2,只需要在线程t1中将线程t2对象的中断标识置为true,然后线程t2可以选择在合适的时候处理该中断请求,甚至可以不理会该请求,就像这个线程没有被中断一样。

关于线程的中断/打扰有三个重要方法,interrupt,isInterrupted,interrupted

interrupt: 中断(打扰)线程。

interrupted:静态方法,测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(即线程状态为非中断状态,而其实已经是终端状态,知识没有了这个终端标识了而已)。

isInterrupted: 测试线程是否已经中断。这个方法不是静态的,调用是需要对象引用,而且这个方法不会清空中断标志。

当另一个线程通过调用 Thread.interrupt() 中断一个线程时,会出现以下两种情况之一。一种情况正常的话会设置该线程的终端状态,但是如果那个线程在执行一个低级可中断阻塞方法,例如Thread.sleep()、 Thread.join() 或 Object.wait(),那么它将取消阻塞并抛出 InterruptedException

注意:j2se 1.2开始,stop,suspend,resume方法就已经不提倡使用了,因为他们容易造成死锁。

这个中断的例子匆忙举出一个是不太准确的,后面会专门写一个文章来测试这个用法。

  1. 7.  守护线程和非守护线程

JVM中存在两种线程:用户线程和守护线程。

所谓的守护线程,是指用户程序在运行的时候后台提供的一种通用服务的线程,比如用于垃圾回收的

垃圾回收线程。这类线程并不是用户线程不可或缺的部分,只是用于提供服务的"服务线程"。

基于这个特点,当虚拟机中的用户线程全部退出运行时,守护线程没有服务的对象后,JVM也就退出了,反之还有任意一个用户线程在,JVM都不会退出。

我们如何开始一个自定义的守护进程呢?正如上述代码一样,答案很简单,就是在Thread.start()方法之前使用setDaemon(true)方法,通过此方法将Thread类中的boolean daemon=true;JVM就会将该线程归为守护线程

说完了守护线程如何产生和特点,下面简要的谈谈使用守护线程应该注意的地方。

1、thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个异常。你不能把正在运行

的常规线程设置为守护线程。

2、在守护线程中产生的线程也是守护线程。(这点读者可结合工具自己验证)

3、我们自己产生的守护线程应该避免访问一些类似于文件、数据库等固有资源,因为由于JVM没有用户

线程之后,守护线程会马上终止。

这一个不做例子,因为在eclipse查看不了jvm退出后其他用户线程的动作,所以查看起来比较复杂,需要用jvisualvm.exe 来看,这一点会再另外写一篇文章阐述。

以上是线程的基本用法,下一篇是关于线程的同步,因为我写的比较详细,也参考了很多资料,希望能把即使比较偏的知识点也囊括进来,如果文章有什么问题和要改进的地方,请提出来大家讨论,我会一一回复,我非常想交一些技术上的朋友。

java 线程基本用法,布布扣,bubuko.com

时间: 2024-10-25 17:32:59

java 线程基本用法的相关文章

java 线程池用法

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) 下面解释下一下构造器中各个参数的含义: corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系.在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除

在Java 线程中返回值的用法

http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread 有时在执行线程中需要在线程中返回一个值:常规中我们会用Runnable接口和Thread类设置一个变量:在run()中改变变量的值,再用一个get方法取得该值,但是run何时完成是未知的:我们需要一定的机制来保证. 在在Java se5有个Callable接口:我们可以用该接口来完成该功能: 代码如: Java代码   package com.thr

浅聊JAVA 线程池的一般用法

一.为什么要用线程池 1).降低资源消耗,通过重复利用已创建的线程降低线程的创建和销毁造成的消耗. 2).提高响应速度,当任务到达时,任务可以不需要等到线程创建就能立即执行. 3).提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控. 二.注意 1).需要对线程池原理了如指掌. 三.线程的常见用法 1).New Thread. 2).Thread Pool. 四.New Thread 常见用法 new  thr

JAVA线程安全之synchronized关键字的正确用法

JAVA线程安全关于synchronized关键字的用法,今天才知道原来我一直错了.以为用了synchronized关键字包住了代码就可以线程同步安全了. 测试了下.发现是完全的错了.synchronized必须正确的使用才是真正的线程安全...虽然知道这种写法,一直以为却由于懒而用了错误的方法. 看来基础还没有打好.仍需复习加强!工作中犯这种错误是不可原谅的,要知道使用synchronized关键字的地方都是数据敏感的!汗一把... 先贴代码: [java] view plaincopypri

Java集合的线程安全用法

线程安全的集合包含2个问题 1.多线程并发修改一 个 集合 怎么办? 2.如果迭代的过程中 集合 被修改了怎么办? a.一个线程在迭代,另一个线程在修改 b.在同一个线程内用同一个迭代器对象进行迭代.修改.迭代.修改. . . 共有有3种解决方案 1.用老的Vector/Hashtable类,上面2个问题都不用担心. Vector/Hashtable所提供的所有方法都是 synchronized的.如果 迭代的过程中数据结构被修改了,迭代器可以反映最新的修改,也不会抛异常.但这种方法效率低下,不

java线程详细介绍

目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1

Java线程:概念与原理

一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运行的exe就是一个进程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. "同时"执行是人的感觉,在线程之间实际上轮换执行. 二.Java中的线程 在J

Java线程:创建与启动

Java线程:创建与启动 一.定义线程 1.扩展java.lang.Thread类. 此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法:否则,该方法不执行任何操作并返回.   Thread 的子类应该重写该方法. 2.实现java.lang.Runnable接口. void run() 使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独

Java线程(一)

1. java什么叫线程安全?什么叫不安全? 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问 什么叫线程安全: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口