多线程的使用

简介: 首先讲一下进程和线程的区别:    进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。
首先讲一下进程和线程的区别:

    进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。

    线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

    线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

    多进程是指操作系统能同时运行多个任务(程序)。

    多线程是指在同一程序中有多个顺序流在执行。

  在java中创建一个线程有两种方法:

    ①实现java.lang.Runnable接口,重写run()方法,启动:new Thread(this).start()。

复制代码
 1 package com.thread;
 2 
 3 public class ThreadTest1 {
 4     public static void main(String[] args) {
 5         Runnable1 r = new Runnable1();
 6         //r.run();并不是线程开启,而是简单的方法调用
 7         Thread t = new Thread(r);//创建线程
 8         //t.run(); //如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
 9         t.start(); //线程开启
10         for (int i = 0; i < 100; i++) {
11             System.out.println("main:"+i);
12         }
13     }
14 }
15 class Runnable1 implements Runnable{
16     public void run() {
17         for (int i = 0; i < 100; i++) {
18             System.out.println("Thread-----:"+i);
19         }
20     }
21 }
复制代码

  要注意的是:

    1.r.run()并不是启动线程,而是简单的方法调用。

    2.Thread也有run()方法,如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

    3.并不是一启动线程(调用start()方法)就执行这个线程,而是进入就绪状态,什么时候运行要看CUP。

    ②继承java.lang.Thread类,重写run()方法。

复制代码
 1 package com.thread;
 2 
 3 public class TestThread2 {
 4     public static void main(String[] args) {
 5         Thread1 t = new Thread1();
 6         //t.run(); //这里也不能直接调用方法
 7         t.start();
 8         for (int i = 0; i < 100; i++) {
 9             System.out.println("main:"+i);
10         }
11     }
12 }
13 
14 //尽量使用实现Runnnable接口,因为接口比较灵活
15 class Thread1 extends Thread{
16     @Override
17     public void run() {
18         for (int i = 0; i < 100; i++) {
19             System.out.println("Thread-----:"+i);
20         }
21     }
22 }
复制代码

虽然两种方法都可行,但是最好还是用第一种方法,因为使用接口灵活性好,java中时单继承、多实现。

Thread类中常用的方法有:

  ①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。

复制代码
 1 package com.thread;
 2 import java.util.Date;
 3 /**
 4  * sleep()指在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
 5  * @author Administrator
 6  *
 7  */
 8 public class SleepTest {
 9     public static void main(String[] args) {
10         Thread2 t = new Thread2();
11         t.start();
12         try {
13             Thread.sleep(10000); //主线程睡眠10秒钟
14         } catch (InterruptedException e) {
15             e.printStackTrace();
16         }
17         //主线程睡眠10秒钟后结束t线程
18         //t.interrupt(); //这种结束方式比较粗暴,如果t线程打开了某个资源还没来得及关闭也就是run方法还没有执行完就强制结束线程,会导致资源无法关闭
19         //t.stop();也是结束某个线程,这种方式比interrupt()更粗暴
20         t.flag = false;
21     }
22 }
23 class Thread2 extends Thread{
24     boolean flag = true; //用这种方式结束线程很不错,用一个变量控制run方法什么时候不再执行,不会出现run方法没有执行完毕就结束
25     @Override
26     public void run() { //run方法一结束,整个线程就终止了
27         while(flag){
28             System.out.println("---"+new Date()+"---");
29             try {
30                 sleep(1000);
31             } catch (InterruptedException e) {
32                 return;
33             }
34         }
35     }
36 }
复制代码

 

  ②join():指等待t线程终止。也可以理解为将t线程合并到当前线程来,等待t线程结束后再往下执行。相当于方法调用

复制代码
 1 package com.thread;
 2 
 3 import java.util.Date;
 4 
 5 /*
 6  * t.join()方法指等待t线程终止。也可以理解为将t线程合并到当前线程来,等待t线程结束后再往下执行。相当于方法调用
 7  */
 8 public class TestJoin {
 9     public static void main(String[] args) {
10         Thread t = new Thread3("abc");
11         t.start();
12         for (int i = 0; i < 20; i++) {
13             System.out.println("我是main线程");
14             if(i==10){
15                 try {
16                     t.join();
17                 } catch (InterruptedException e1) {
18                     // TODO Auto-generated catch block
19                     e1.printStackTrace();
20                 }
21             }
22             try {
23                 Thread.sleep(1000);
24             } catch (InterruptedException e) {
25                 e.printStackTrace();
26             }
27         }
28     }
29 }
30 class Thread3 extends Thread{
31     public Thread3(String s) { //给该线程取一个名字,用getName()方法可以去到该名字
32         super(s);
33     }
34     @Override
35     public void run() {
36         for (int i = 0; i < 20; i++) {
37             System.out.println("我是"+getName()+"线程");
38             try {
39                 sleep(1000);
40             } catch (InterruptedException e) {
41                 e.printStackTrace();
42             }
43         }
44     }
45 }
复制代码

运行该程序结果为:

复制代码
 1 我是main线程
 2 我是abc线程
 3 我是main线程
 4 我是abc线程
 5 我是main线程
 6 我是abc线程
 7 我是main线程
 8 我是abc线程
 9 我是main线程
10 我是abc线程
11 我是main线程
12 我是abc线程
13 我是main线程
14 我是abc线程
15 我是main线程
16 我是abc线程
17 我是main线程
18 我是abc线程
19 我是main线程
20 我是abc线程
21 我是main线程
22 我是abc线程
23 我是abc线程
24 我是abc线程
25 我是abc线程
26 我是abc线程
27 我是abc线程
28 我是abc线程
29 我是abc线程
30 我是abc线程
31 我是abc线程
32 我是main线程
33 我是main线程
34 我是main线程
35 我是main线程
36 我是main线程
37 我是main线程
38 我是main线程
39 我是main线程
40 我是main线程
复制代码

可以看到从第22行起就开始顺序执行了,因为i=10的时候就将该形成合并了。

  ③yield():暂停当前正在执行的线程对象,并执行其他线程。

  ④setPriority(): 更改线程的优先级。

    MIN_PRIORITY = 1
       NORM_PRIORITY = 5
           MAX_PRIORITY = 10

复制代码
 1 package com.thread;
 2 
 3 
 4 /*t.yield()暂停当前正在执行的线程对象,并执行其他线程。
 5  * 
 6  * MIN_PRIORITY 1
 7  * NORM_PRIORITY 5
 8  * MAX_PRIORITY 10
 9  */
10 public class TestYield {
11     public static void main(String[] args) {
12         Thread4 t1 = new Thread4("t1");
13         Thread4 t2 = new Thread4("t2");
14         t1.setPriority(Thread.MAX_PRIORITY);
15         t2.setPriority(Thread.MIN_PRIORITY);
16         System.out.println(t1.getPriority());
17         System.out.println(t2.getPriority());
18         t1.start();
19         t2.start();
20         
21     }
22 }
23 class Thread4 extends Thread{
24     public Thread4(String s) { 
25         super(s);
26     }
27     @Override
28     public void run() {
29         for (int i = 0; i < 1000; i++) {
30             System.out.println("我是"+getName()+"线程"+i);
31             if(i%10 == 0){
32                 yield();
33             }
34         }
35     }
36 }
复制代码

由于运行结果太长就没有贴上来了,运行该程序,可以看到t1和t2两个进程每次当i为10的倍数时都会让给其他线程执行。

  ⑤interrupt():中断某个线程,这种结束方式比较粗暴,如果t线程打开了某个资源还没来得及关闭也就是run方法还没有执行完就强制结束线程,会导致资源无法关闭

  要想结束进程最好的办法就是用sleep()函数的例子程序里那样,在线程类里面用以个boolean型变量来控制run()方法什么时候结束,run()方法一结束,该线程也就结束了。

  ⑥还有很多的方法就不一一列举了.........

相关文章
|
Java API 调度
|
30天前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
38 1
C++ 多线程之初识多线程
|
5月前
多线程知识
多线程知识
20 1
|
6月前
|
安全 Java C#
C#多线程详解
C#多线程详解
55 0
|
6月前
|
C#
[C#] 多线程的使用
[C#] 多线程的使用
44 0
多线程
java多线程是指在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。Java中所有变量都储存在主存中,对于所有线程都是共享的。Java中的多线程可以通过继承Thread类或者实现Runnable接口来创建,然后通过start()方法来启动线程。Java中的多线程可以提高程序的并发性和执行效率。
|
Linux 调度
多线程具体实现(上)
多线程具体实现
78 0
|
存储 安全 Java
多线程1
多线程1-https://www.nowcoder.com/issue/tutorial?tutorialId=94&uuid=4e79fb9392af4f90b898311e8c1efe36
64 0