JAVA 多线程学习总结

新手一枚,Java学习中,把自己学习多线程的知识总结一下,梳理下知识,方便日后查阅,高手莫进。

本文的主要内容:

[1]    实现线程的两种方法                [2]  线程的启动与停止

[3]     线程的互斥                           [4]  线程协作

[5]   线程Join                                [6]Object实现生产者、消费者问题

[7]Lock类实现生产者、消费者问题    [8] 线程优先级

[9]守护线程(daemon线程)           [10]线程池概念

一 实现线程的两种方法

JAVA中实现线程,有两种方法。一种是 扩展 Threaad 类,一种是实现package java.lang.Runnble接口。

首先来看看这JAVA API文档中如何定义这两个:

Runnble接口

package java.lang;
public interface Runnable {
public abstract void run();
}

这个接口的定义很简单,只是定义了一个方法。

Threaad 类

package java.lang;
public
class Thread implements Runnable {
/* What will be run. */
    private Runnable target;
 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
    .........
        this.target = target;
    ........
    }
 public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
 public synchronized void start() {
    ........
}

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

  可以看出,Thread 也是实现了Runnable接口,用start()方法启动Therad()对象时,调用 实现Runnable接口所实现的run()方法。

这个弄明白了,关于线程的启动与停止就很容易搞明白了。

二、线程的启动与停止

(1)启动一个线程必须调用Thread的start()方法,如果线程类继承Thread,则可以直接调用对象的start()方法启动,如果线程类实现的是Runnable接口,则需要将对象封装成Thread,再调用封装后对象的start();

(2)JAVA只允许单继承,因此当一个类继承另一个类,又想成为一个线程时,就不能继承Thread类了,只能通过实现Runnable接口来实现。

(3)线程的停止方法有

[1] 让线程的run()方法执行完,线程自然结束。(这种方法最好)

[2]通过轮询和共享标志位的方法来结束线程,例如while(flag){},flag的初始值设为真,当需要结束时,将flag的值设为false。(这种方法也不很     好,因为如果while(flag){}方法阻塞了,则flag会失效)

[3]使用interrupt(),而程序会丢出InterruptedException例外,因而使得执行绪离开run()方法。

[4]使用stop()方法终止线程,在上一个版本的JDK中,sun公司已经说明:Thread.stop, Thread.suspend and Thread.resume都已经不被推荐使用。因为会导致程序出现不可想象的状况。

小例子如下:

 1 package com.beiyan.thread;
 2
 3 public class ThreadStartStop {
 4
 5     public static void main(String[] args) throws InterruptedException {
 6         ThreadStartStop startStop = new ThreadStartStop();
 7         ThreadA a = startStop.new ThreadA();// ThreadA和ThreadB
 8         ThreadB tb = startStop.new ThreadB(); // 是内部类,所以要先实例化主类,才能new两个线程对象
 9         a.start(); // ThreadA extends Thread 可以直接启动,
10         Thread b = new Thread(tb);// ThreadB implements Runnable
11         b.start(); // 必须要先实例化一个Thread 对象,在Thread 对象里面启动
12
13         Thread.sleep(3000);// 主线程休息3秒
14         a.StopThread();
15         System.out.println("---------用 interupt()终止线程----------");
16         ThreadC c = startStop.new ThreadC();
17         c.start();
18         c.interrupt();
19
20     }
21
22     class ThreadA extends Thread {
23         private boolean running = false;
24
25         // 重写Start方法
26         public void start() {
27             System.out.println("ThreadA启动");
28             this.running = true;
29             super.start();
30         }
31
32         // run方法
33         public void run() {
34
35             try {
36                 while (running) {
37                     Thread.sleep(4000);
38                     System.out.println("ThreadA 执行中。。。");
39
40                     // wait();
41                 }
42             } catch (InterruptedException e) {
43                 System.out.println("ThreadA end!");
44             }
45         }
46
47         // 自定义线程停止方法
48         public void StopThread() {
49             System.out.println("ThreadA Stop");
50             running = false;
51         }
52     }
53
54     class ThreadB implements Runnable {
55
56         @Override
57         public void run() {
58
59             System.out.println("ThreadB执行中。。。");
60             try {
61                 Thread.sleep(1000);
62             } catch (InterruptedException e) {
63                 System.out.println("ThreadB Stop");
64             }
65             System.out.println("ThreadB 结束");
66         }
67
68     }
69
70     class ThreadC extends Thread {
71
72         // 重写Start方法
73         public void start() {
74             System.out.println("ThreadC启动");
75             super.start();
76         }
77
78         // run方法
79         public void run() {
80
81             try {
82                 while (!Thread.interrupted()) {
83                     Thread.sleep(3000);
84                     System.out.println("ThreadC 执行中。。。");
85                     // wait();
86                 }
87             } catch (InterruptedException e) {
88                 System.out.println("ThreadC end!");
89             }
90         }
91
92     }
93 }

运行结果如下:

ThreadA启动
ThreadB执行中。。。
ThreadB 结束
ThreadA Stop
---------用 interupt()终止线程----------
ThreadC启动
ThreadA 执行中。。。

可以看出:

1、ThreadA是采用 flage标志位的方式终止线程的,最后一句结果是:ThreadA 执行中。。。当线程终止后,线程A还在继续执行,可见采用while(flag){}方法终止线程时,若线程出现Sleep()或者wait()阻塞时,并不能很好的结束线程。

2、ThreadC是采用interrupt()方法终止线程的。程序会丢出InterruptedException异常,因而使得执行绪离开run()方法。

3、线程ThreadA 和ThreadB 的启动方式。

三、线程的互斥

  在操作系统中,有临界区,某些时刻只允许一个进程访问临界区。在Java中,对象也有临界区。在某些时候只允许一个线程访问临界区,称为线程的互斥。

在类的方法中使用synchronized()关键字可以保证同一时刻只有一个线程进入该方法。

 1 public class Synchronized {
 2
 3     private int money = 1000;
 4     private int money2 = 1000;
 5
 6     // 用synchronized关键字定义一个同步的方法。
 7     public synchronized void add(int p) {
 8         System.out.println("已有money: " + money + "   存入: " + p + "  总共:" + (money + p));
 9         money += p;
10     }
11
12     // 没有使用synchronized
13     public void add2(int p) {
14         System.out.println("已有money2: " + money2 + "   存入: " + p + "  总共:" + (money2 + p));
15         money2 += p;
16     }
17
18     public static void main(String[] args) {
19         Synchronized sync = new Synchronized();
20         // 没有使用synchronized,进行线程互斥
21         ThreadTest2 p1 = new ThreadTest2(sync, 300);
22         ThreadTest2 p2 = new ThreadTest2(sync, 200);
23         ThreadTest2 p3 = new ThreadTest2(sync, 100);
24         p1.start();
25         p2.start();
26         p3.start();
27         // 使用synchronized,进行线程互斥
28         ThreadTest t1 = new ThreadTest(sync, 300);
29         ThreadTest t2 = new ThreadTest(sync, 200);
30         ThreadTest t3 = new ThreadTest(sync, 100);
31         t1.start();
32         t2.start();
33         t3.start();
34     }
35
36 }
37
38 // 定义一个线程类,用于增加money
39 class ThreadTest extends Thread {
40     private Synchronized syn = null;
41     private int moneyAdd = 0;
42
43     public ThreadTest(Synchronized synchronized1, int money)
44     {
45         this.syn = synchronized1;
46         this.moneyAdd = money;
47     }
48
49     public void run() {
50         syn.add(moneyAdd);
51     }
52 }
53
54 // 定义一个线程类,用于增加money2
55 class ThreadTest2 extends Thread {
56     private Synchronized syn = null;
57     private int moneyAdd = 0;
58
59     public ThreadTest2(Synchronized synchronized1, int money)
60     {
61         this.syn = synchronized1;
62         this.moneyAdd = money;
63     }
64
65     public void run() {
66         syn.add2(moneyAdd);
67     }
68 }

运行结果如下:

已有money2: 1000 存入: 300 总共:1300
已有money2: 1000 存入: 200 总共:1200
已有money2: 1000 存入: 100 总共:1100
已有money: 1000 存入: 300 总共:1300
已有money: 1300 存入: 200 总共:1500
已有money: 1500 存入: 100 总共:1600

money2是没有使用synchronized进行同步处理的。

money是使用synchronized进行同步处理的。

可见使用synchronized同步机制实现线程的互斥运行,从而避免出现错误。

四、线程协作

有时候多个线程需要协作,线程A往缓冲区里面写数据,线程B从缓冲区里读取数据,当缓冲区满时,线程A必须等待;当缓冲区为空时,线程B必须等待。

在synchronized代码块里使用wait()方法,能够使当前线程进入等待状态,并释放当前线程用于的对象锁。

在synchronized代码块里使用notify()或者notifyall()方法可以使当前线程释放对象锁,并唤醒其他正在等待该对象锁的线程。当有多个线程在等待该对象锁时,由Java虚拟机决定被唤醒的进程。

例子如下:

 1 package com.beiyan.thread;
 2
 3 import java.util.Vector;
 4
 5 public class WaitNotify {
 6     // 内部类,实现task的减少和增加
 7     class ThreadTask extends Thread {
 8         private Vector task = new Vector();
 9
10         public void run() {
11             while (!Thread.interrupted()) {
12                 synchronized (this) {
13                     while (task.size() == 0) {
14                         System.out.println("资源紧张,进入等待。。。");
15                         try {
16                             wait();
17                             System.out.println("等待结束。。。");
18                         } catch (InterruptedException e) {
19                             // TODO Auto-generated catch block
20                             e.printStackTrace();
21                         }
22                     }
23                     try {
24                         sleep(1000);
25                         System.out.println("做完了一个任务");
26                         task.remove(task.size() - 1);
27                     } catch (InterruptedException e) {
28                         // TODO Auto-generated catch block
29                         e.printStackTrace();
30                     }
31                 }
32             }
33         }
34
35         // 增加task 供使用
36         public void addTask(String str) {
37             synchronized (this) {
38                 task.add(str);
39                 System.out.println("增加了一个任务");
40                 notify();
41             }
42         }
43     }
44
45     public static void main(String[] args) throws InterruptedException {
46         WaitNotify notify = new WaitNotify();
47         ThreadTask task = notify.new ThreadTask();
48         task.start();
49         Thread.sleep(1000);
50         for (int i = 0; i < 3; i++) {
51             task.addTask("str" + i);
52             Thread.sleep(1000);
53         }
54
55     }
56 }

从例子可以看出,task线程中,调用start(),进而执行run()方法的内容,让没有资源(工作任务)时,task线程进入wait()状态,释放对线程对象的锁,这时main线程调用task的addTask()方法,使任务增加一个,调用notify()方法并通知线程,有资源可以继续执行。

五、线程join

有时候一个线程需要等待其他线程执行完毕后再进行操作,这是一种等待关系,也是一种协作。

在当前线程中调用线程A的join(参数 b),表示:当前线程必须等待线程A执行长为 b 的时间再能继续执行。

若参数为空,则表示 线程A执行完之后,当前线程才能继续执行。

例子如下:

 1 package com.beiyan.thread;
 2
 3 public class Join {
 4     class ThreadA extends Thread {
 5         private int id;
 6         private String name;
 7
 8         public ThreadA(int a, String b)
 9         {
10             this.id = a;
11             this.name = b;
12         }
13
14         public void run() {
15             int i = 0;
16             while (i < 5) {
17                 System.out.println(this.name + " 执行中。。。");
18                 try {
19                     Thread.sleep(500);
20                 } catch (InterruptedException e) {
21                     e.printStackTrace();
22
23                 }
24                 i++;
25             }
26         }
27     }
28
29     public static void main(String[] args) throws InterruptedException {
30         Join join = new Join();
31         ThreadA a = join.new ThreadA(1, "线程A");
32         a.start();
33         a.join(); // 线程A并入主线程,线程A执行完毕后,下面的for语句,才开始执行
34
35         for (int i = 0; i < 5; i++) {
36             System.out.println("Main Thread.....");
37         }
38     }
39 }

执行结果如下:

线程A 执行中。。。
线程A 执行中。。。
线程A 执行中。。。
线程A 执行中。。。
线程A 执行中。。。
Main Thread.....
Main Thread.....
Main Thread.....
Main Thread.....
Main Thread.....

线程A join()主线程后,成为主线程的一部分,合并成一个线程,所以按顺序执行。

六、Object实现生产者、消费者问题

  生产者,消费者问题是一个多线程协作问题,生产者负责生产产品,并存入仓库,消费者从仓库中获得产品并消费。

例子如下:

 1 package com.beiyan.thread;
 2
 3 import java.util.LinkedList;
 4
 5 public class ProdutConsume extends Thread {
 6
 7     private LinkedList<Object> wareHouse = new LinkedList<Object>();
 8     private final int MAX = 4;
 9
10     // 生产者内部类
11     class Produt extends Thread {
12         public void run() {
13
14             while (!Thread.interrupted()) {
15                 synchronized (wareHouse) {
16                     try {
17                         while (wareHouse.size() == MAX) {
18                             System.out.println("仓库已满,正在等待消费");
19                             wareHouse.wait();
20
21                         }
22                         Object obj = new Object();
23                         if (wareHouse.add(obj)) {
24                             System.out.println("生产一个新产品");
25                             Thread.sleep((long) (Math.random() * 1000));
26                             wareHouse.notify();
27                         }
28                     } catch (InterruptedException e) {
29                         System.out.println("Producter Stop!!");
30                     }
31
32                 }
33             }
34
35         }
36     }
37
38     // 消费者内部类
39     class Comsumer extends Thread {
40
41         public void run() {
42
43             while (!Thread.interrupted()) {
44                 synchronized (wareHouse) {
45                     try {
46                         while (wareHouse.size() == 0) {
47                             System.out.println("仓库为空,正在等待");
48                             wareHouse.wait();
49                         }
50                         wareHouse.removeLast();
51                         System.out.println("消费一个新产品");
52                         Thread.sleep((long) (Math.random() * 500));
53                         wareHouse.notify();
54                     } catch (InterruptedException e) {
55                         System.out.println("Comsumer Stop!!");
56                     }
57
58                 }
59             }
60
61         }
62     }
63
64     public static void main(String[] args) throws InterruptedException {
65         ProdutConsume ps = new ProdutConsume();
66         Produt produt = ps.new Produt();
67         Comsumer comsumer = ps.new Comsumer();
68         produt.start();
69         comsumer.start();
70
71     }
72 }

七、Lock类 实现生产者、消费者问题

  java JDK1.5版本后,出现了Condition。它用来替代传统的Object的wait()、notify()实现线程间的协作。使用Condition的await()、signal()这种方式实现线程间协作,比传统方式更加安全和高效。

  synchronized却只有一把锁,lock类可以有多把锁,比较灵活。对于生产者消费者问题,可以对仓库的满和空各设一把锁。

举个例子:

当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。

  但是采用synchronized关键字来实现同步的话,就会导致一个问题:

  如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。

  因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到。

代码:

 1 package com.beiyan.thread;
 2
 3 import java.awt.Container;
 4 import java.util.LinkedList;
 5 import java.util.concurrent.TimeUnit;
 6 import java.util.concurrent.locks.Condition;
 7 import java.util.concurrent.locks.Lock;
 8 import java.util.concurrent.locks.ReentrantLock;
 9
10 public class ProductConsumer2 extends Thread {
11
12     private LinkedList<Object> wareHouse = new LinkedList<Object>();
13     private final int MAX = 4;
14     private final Lock lock = new ReentrantLock();
15     private Condition full = lock.newCondition();
16     private Condition empty = lock.newCondition();
17
18     // 生产者内部类
19     class Produt extends Thread {
20         public void run() {
21
22             while (!Thread.interrupted()) {
23                 lock.lock();
24                 try {
25                     while (wareHouse.size() == MAX) {
26                         System.out.println("仓库已满,正在等待消费");
27                         full.await();
28                     }
29                     Object obj = new Object();
30                     if (wareHouse.add(obj)) {
31                         System.out.println("生产一个新产品");
32                         Thread.sleep((long) (Math.random() * 1000));
33                         empty.signal();
34                     }
35                 } catch (InterruptedException e) {
36                     System.out.println("Producter Stop!!");
37                 }
38                 lock.unlock();
39
40             }
41         }
42
43     }
44
45     // 消费者内部类
46     class Comsumer extends Thread {
47
48         public void run() {
49             while (!Thread.interrupted()) {
50                 lock.lock();
51                 try {
52                     while (wareHouse.size() == 0) {
53                         System.out.println("仓库为空,正在等待");
54                         empty.await();
55                     }
56                     wareHouse.removeLast();
57                     System.out.println("消费一个新产品");
58                     Thread.sleep((long) (Math.random() * 500));
59                     full.signal();
60                 } catch (InterruptedException e) {
61                     System.out.println("Comsumer Stop!!");
62                 }
63                 lock.unlock();
64
65             }
66
67         }
68     }
69
70     public static void main(String[] args) throws InterruptedException {
71         ProductConsumer2 ps = new ProductConsumer2();
72         Produt produt = ps.new Produt();
73         Comsumer comsumer = ps.new Comsumer();
74         produt.start();
75         comsumer.start();
76
77     }
78 }

运行结果如下:

生产一个新产品
生产一个新产品
生产一个新产品
生产一个新产品
仓库已满,正在等待消费
消费一个新产品
消费一个新产品
消费一个新产品
消费一个新产品
仓库为空,正在等待
生产一个新产品
生产一个新产品
生产一个新产品
生产一个新产品
仓库已满,正在等待消费
消费一个新产品
消费一个新产品
消费一个新产品
消费一个新产品
仓库为空,正在等待
生产一个新产品
生产一个新产品

八、线程优先级

与操作系统中的进程一样,Java线程也有优先级,在同等情况下,对于两个同时启动的线程,优先级高的先执行。

Java线程优先级分为10个级别,数字越大,级别越高,默认为5;

Thread 的setPriority()可以设置线程的优先级。

代码如下:

 1 package com.beiyan.thread;
 2
 3 public class Priority {
 4     public static void main(String[] args) {
 5         Priority priority = new Priority();
 6         ThreadPriority t1 = priority.new ThreadPriority(1);
 7         ThreadPriority t2 = priority.new ThreadPriority(2);
 8         System.out.println("线程t2的默认优先级: " + t2.getPriority());
 9         t1.setPriority(6);
10         t1.start();
11         t2.start();
12     }
13
14     class ThreadPriority extends Thread {
15         private int id;
16
17         public ThreadPriority(int a)
18         {
19             this.id = a;
20         }
21
22         public void run() {
23             for (int i = 1; i < 5; i++) {
24                 System.out.println("Thread " + id + " 正在执行。。。。");
25                 try {
26                     Thread.sleep((long) (Math.random() * 2000));
27                 } catch (InterruptedException e) {
28                     System.out.println("Thread " + id + " interrupt");
29                 }
30             }
31         }
32     }
33 }

执行结果:

线程t2的默认优先级: 5
Thread 1 正在执行。。。。
Thread 2 正在执行。。。。
Thread 1 正在执行。。。。
Thread 1 正在执行。。。。
Thread 1 正在执行。。。。
Thread 2 正在执行。。。。
Thread 2 正在执行。。。。
Thread 2 正在执行。。。。

线程1的优先级设置为6时,级别比线程2高,故线程1比线程2优先执行。

九、守护线程

有一种线程叫做守护线程(Daemon线程),如Java虚拟机的垃圾回收线程,它们在后台运行,为非守护线程提供服务。

Thread的setDaemon实例方法设置线程是否为守护线程,参数为true表示该线程为守护线程。

线程运行后,setDaemon实例方法无效,即必须在调用start()方法之前调用setDaemon方法。

程序中启动的线程默认为非守护线程,但在守护线程中启动的线程都是守护线程。

当程序中,所有的非守护线程都结束时,守护线程自动结束。

例子如下:

 1 package com.beiyan.thread;
 2
 3 public class Daemon {
 4
 5     public static void main(String[] args) {
 6
 7         Thread t1 = new MyCommon();
 8
 9         Thread t2 = new Thread(new MyDaemon());
10
11         t2.setDaemon(true); // 设置为守护线程
12
13         t2.start();
14
15         t1.start();
16     }
17 }
18
19 //普通user线程
20 class MyCommon extends Thread {
21     public void run() {
22
23         for (int i = 0; i < 4; i++) {
24
25             System.out.println("用户第" + i + "次执行!");
26
27             try {
28
29                 Thread.sleep(100);
30             }
31
32             catch (InterruptedException e) {
33
34                 e.printStackTrace();
35             }
36         }
37
38     }
39 }
40
41 // 守护线程,守护线程要设置为无限循环,或者运行时间长一点,不然用户线程(非守护)还没结束,守护线程已经结束。
42 class MyDaemon implements Runnable {
43
44     public void run() {
45
46         int i = 0;
47         try {
48             while (true) {
49
50                 System.out.println("守护线程第" + i + "次执行!");
51
52                 Thread.sleep(100);
53
54                 i++;
55
56             }
57         } catch (
58
59         InterruptedException e) {
60
61             e.printStackTrace();
62
63         } finally {
64             System.out.println("守护线程结束");// 验证守护线程的finally是否执行
65         }
66
67     }
68 }

运行结果如下:

用户第0次执行!
守护线程第0次执行!
守护线程第1次执行!
用户第1次执行!
守护线程第2次执行!
用户第2次执行!
守护线程第3次执行!
用户第3次执行!
守护线程第4次执行!

可以看出,在普通用户线程结束运行后,虽然守护线程没执行完,但也立即结束。

并且,守护线程finally()部分的代码是不执行的。

学习异常时说,finall()最后必须执行的。但对于守护线程来说不适用。

十 、线程池

在进行socket网络编程时,往往需要多个服务器都能连接到服务器,服务器为每个连接到服务器的用户开你一个线程进行处理,假如连接到服务器上的用户非常多,那么服务器的线程就会越用越少,最好的解决办法是使用线程池。

服务器启动时,分配何时数量的线程到一个线程池内,当有用户连上服务器之后,服务器从线程池中分配一个线程给用户,当线程池的线程分配完毕后,其他新连接的用户处于等待状态。

当有用户与服务器断开连接后,服务器重新分配线程。

具体例子放到下一篇Socket网络编程总结里面吧。

最后,激励下自己:

学习编程切忌浮躁,天亮后,面包会有的,牛奶会有的。

时间: 2024-08-05 15:27:39

JAVA 多线程学习总结的相关文章

java多线程学习(3)

1)竞争条件 在实际的多线程应用中,通常会有两个或多个线程需要对共同的对象进行共享访问,如果两个线程访问相同的对象,而且每一个都调用了一个会改变对象状态的方法, 那么,线程就会相互倾轧.根据各个线程访问数据的不同顺序,可能会产生腐蚀现象.这种情况通常称为竞争条件. 2)同步 为了多个线程对共享数据的腐蚀,就需要对数据的存取实现同步:常用的同步方法有3种: 1.Reenlock 用Reenlock保护代码块的基本机构如下: 1 Lock myLock=new ReenLock; 2 3 myLoc

java多线程学习(2)

1)Callable和Future Runnable封装一个异步运行的任务:可以当成一个没有任何参数和返回值的异步方法,Callable和 Runnable类似,但是它有返回值和参数. Callable接口是一个参数化的类型,只有一个方法call. 1 public interface Callable<V> 2 3 { 4 5 V call()throws Exception; 6 7 } 类型参数v是指返回值的类型,例如Callable<Integer>代表最终返回一个Inte

java多线程学习(1)

1)多线程与多进程的区别 多线程和多进程有什么区别呢?本质的区别在于每个进程有它自己的变量的完备集,线程则共享相同的数据. 对程序来说,共享的变量会使得线程之间的通信比进程间的通信更加有效和简单:同时,线程相对于进程来说,更加的“轻量级”, 线程的创建和销毁要比 进程的 开销要小的多. 2)多线程程序的构造 多线程的构造通常有两种方法, 第一种方法是,构建一个Thread的子类,并重写它的run()方法: 1 class MyThread extends Thread 2 { 3 4 publi

java多线程学习--java.util.concurrent

CountDownLatch,api 文档:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 假设我们要打印1-100,最

java 多线程学习(一)

1 public class ThreadA extends Thread { 2 private static int threadID = 0; 3 4 public ThreadA() { 5 super("ThreadID:" + (++threadID)); 6 } 7 8 public void run() { 9 try { 10 System.out.println(getName() + " 线程运行开始!"); 11 for (int i = 0

黑马程序员之Java多线程学习

android培训  java培训 期待与您交流! 这一篇文章主要关于java多线程,主要还是以例子来驱动的.因为讲解多线程的书籍和文章已经很多了,所以我也不好意思多说,呵呵.大家可以去参考一些那些书籍.我这个文章主要关于实际的一些问题.同时也算是我以后复习的资料吧,.呵呵大家多多指教. 同时希望多结交一些技术上的朋友.谢谢. -------------------------------------------------------------------------------------

Java多线程学习幸运飞艇采集器修复

package javastudy01; class MyThread extends Thread {//重写Run方法public void run(){//1.获取当前线程的名字System.out.println(this.getName()+"我是一个线程."); } public static void main(String[] args) {Java多线程学习幸运飞艇采集器修复,需要请搜索[大神源码论坛]dsluntan.com 客服企娥3393756370 V信170

[转]Java多线程学习(总结很详细!!!)

Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的线程函数用法.概述等.首先让我们来了解下在操作系统中进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

Java多线程学习(详细)

一.进程与线程的区别 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小.(线程是cpu调度的最小单位) 线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止.     多进程是指操作系统能同时运行多个任务(程序).     多线程是指在同一程序中有多个顺序流在执行. 在java中要想实现多线程,有两种手段,一