初识多线程之基础知识与常用方法

Posted 瞿亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识多线程之基础知识与常用方法相关的知识,希望对你有一定的参考价值。

1.线程与进程的描述:

 1.1进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1~n个线程。(进程是资源分配的最小单位)
  

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

 

2.实现多线程的常用方式:

继承Thread类    extends Thread

  实现Runnable接口  implements Runnable

   内部匿名类   

Thread t = new Thread(new Runnable() {    
});

3.实现多线程的常用方式:

推荐使用Runnable接口:原因有二:1 Java中的类仅仅只支持单继承,而接口支持多继承
                                2 使用Runnable接口可以轻松的实现多个线程间的资源共享

 

4.线程的五种状态:

 

5.常用函数说明:

5.1:join线程(控制线程):
                Thread提供了让一个线程等待另一个线程完成的方法--join方法,当在某个程序执行流中调用其他线程的join方法,调用线程将被阻塞,直到被join方法加入的join线程执行完毕为止。

列子:

 1 /**
 2  * Created by 123 on 2017/07/02.
 3  */
 4 public class TestJoin {
 5     public static void main(String[] args) throws InterruptedException {
 6         new JoinThread("新线程").start();
 7         for (int i = 0; i < 10; i++) {
 8                if (i==5){
 9                    JoinThread j1=new JoinThread("被join的线程");
10                    j1.start();
11                    j1.join();
12                }
13             System.out.println(Thread.currentThread().getName()+" "+i);
14         }
15     }
16 }
join方法使用(测试类)
 1 /**
 2  * Created by 123 on 2017/07/02.
 3  */
 4 public class JoinThread extends Thread {
 5     public JoinThread(String name) {
 6         super(name);
 7     }
 8 
 9     public void run(){
10         for (int i=1;i<=10;i++){
11             System.out.println(Thread.currentThread().getName()+"  "+i);
12         }
13     }
14 }
线程执行体

 

5.2:yield线程(线程让步):线程的优先级

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

 1 import javax.naming.Name;
 2 
 3 /**
 4  * Created by 123 on 2017/07/02.
 5  */
 6 public class ThreadYeild extends Thread {
 7     String name;
 8 
 9     public ThreadYeild(String name) {
10         super(name);
11         this.name = name;
12     }
13 
14     @Override
15     public void run() {
16         for (int i = 0; i < 50; i++) {
17             System.out.println(this.getName()+" "+i);
18             if (i==30){
19                 Thread.yield();
20             }
21         }
22     }
23 }
线程执行体
 1 import javax.naming.Name;
 2 
 3 /**
 4  * Created by 123 on 2017/07/02.
 5  */
 6 public class ThreadYeild extends Thread {
 7     String name;
 8 
 9     public ThreadYeild(String name) {
10         super(name);
11         this.name = name;
12     }
13 
14     @Override
15     public void run() {
16         for (int i = 0; i < 50; i++) {
17             System.out.println(this.getName()+" "+i);
18             if (i==30){
19                 Thread.yield();
20             }
21         }
22     }
23 }
Yeild方法(测试类)

 

5.3:sleep()函数和yield函数的区别:

                sleep()和yield()的区别):
                1:sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;
                yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
                2:sleep()函数也可以允许优先级较低的线程运行

5.4守护线程:

 1 /**
 2  * Created by 123 on 2017/07/02.
 3  */
 4 public class BackGroundThread implements Runnable {
 5     public void run() {
 6          for (int i=1;i<100000000;i++){
 7              System.out.println("后台线程执行第"+i+"次");
 8              try {
 9                  Thread.sleep(7);
10              } catch (InterruptedException e) {
11                  e.printStackTrace();
12              }
13          }
14     }
15 }
后台线程
 1 /**
 2  * Created by 123 on 2017/07/02.
 3  */
 4 public class MyThreads extends Thread {
 5     @Override
 6     public void run() {
 7         for (int i = 1; i <= 4; i++) {
 8             System.out.println("线程1第" + i + "次执行");
 9             try {
10                 Thread.sleep(7);
11             } catch (InterruptedException e) {
12                 e.printStackTrace();
13             }
14         }
15     }
16 }
前台线程
 1 /**
 2  * Created by 123 on 2017/07/02.
 3  * 守护线程
 4  */
 5 public class TestThread {
 6     //如果前台线程执行i次,后台线程执行i+1次,因为还有main线程
 7     public static void main(String[] args) {
 8         Thread t1 = new MyThreads();
 9         Thread t2 = new Thread(new BackGroundThread());
10         t2.setDaemon(true);    //设置为守护线程
11         t1.start();
12         t2.start();
13     }
14 }
测试类

结论就是:如果前台线程执行i次,那么后台线程就会执行i+1次,因为还有一个main线程。

5.4:线程的优先级(1~10)
                setPriority(): 更改线程的优先级。

            MIN_PRIORITY = 1
                 NORM_PRIORITY = 5
                      MAX_PRIORITY = 10

 

以上是关于初识多线程之基础知识与常用方法的主要内容,如果未能解决你的问题,请参考以下文章

多线程基础之线程属性

两步帮你搞定多线程之第一步

Java-多线程之初识线程

Java核心知识---初识线程

Java基础之多线程

java基础之多线程总结二(CAS和各种常用锁)