Java多线程详解

线程(Thread)是指程序的运行流程,多线程机制指同时运行多个程序块。

Java中实现多线程有两种方法:继承Thread类;实现Runnable接口。

Thread类的run()方法的制定者:接口Runnable中的run();

Thread类中没有完全实现Runnable接口中的run()方法。

Thread类是Runnable接口的子类,Thread类中的run()方法调用的是Runnable接口中的run()方法。

接口是由全局变量和公共抽象方法所组成的。

所以,在Thread子类中,必须覆写Thread类中的run()方法。

启动线程时,不能直接调用run()方法,而是调用从Thread类中继承而来的start()方法;

即同一个对象只能调用一次start方法。

如果一个类继承了Thread类,那么只能调用一次start()方法,如果多次调用,

将会出现IllegalThreadStateException”异常。

Runnable接口中只有一个方法:run();

RunnableThread中的run方法和自定义的run方法之间的关系:

 1 interface Runnable{
 2     public abstract void run();
 3 }                                //remove method body
 4 
 5 public class Thread implements Runnable {
 6     private Runnable target;                //封装
 7     public Thread(Runnable target,String name){        //构造函数,name是线程的名称
 8         init(target);
 9     }
10     
11     private void init(Runnable target2) {    //检验关口,给属性赋值
12         this.target = target;
13     }
14     
15     public void run() {
16         if(target != null){
17             target.run();    //此run方法指的是自定义的run方法,即Runable中的run方法
18                     //整个过程中,只有一个对象,只有这个对象有能力调用自定
19                     //义的run方法。
20         }    
21     }    
22 }
23 class MyThread implements Runnable{
24     public void run() {                        //自定义的run方法
25         
26     }
27 }

由于使用Runable的整个过程中,只产生一个对象,所以可以方便地实现资源的共享。

这也是Runable优于Thread之处。

Java程序每次运行至少启动两个线程:main线程、垃圾收集线程。

Thread类中常用的方法:

currentThread(静态),通过类名Thread直接调用;

判断线程是否启动(存活)

 1 class MyThread implements Runnable{
 2     public void run(){
 3         for(int i=0;i<3;i++){
 4             System.out.println(Thread.currentThread().getName()+"运行………"+i);
 5         }
 6     }
 7 }
 8 
 9 public class ThreadAliveDemo {
10 
11     public static void main(String[] args) {
12         MyThread mt = new MyThread();
13         Thread t = new Thread(mt);   
14         System.out.println("线程开始执行之前……"+t.isAlive());
15         
16         t.start();
17         
18         for(int i=0;i<5;i++){
19             System.out.println("等待……"+i);//i值的不同,最后运行结果不同
20         }
21         
22         System.out.println("线程开始执行之后……"+t.isAlive());
23         for(int i=0;i<3;i++){
24             System.out.println("main运行……"+i);
25         }
26         System.out.println("代码执行之后……"+t.isAlive());
27     }
28 }

主线程有可能比其他线程先执行完,其他线程不会受到任何影响,不会随着主线程的结束而结束。

线程的强制执行

class MyThread implements Runnable{
    public void run(){
        for(int i=0;i<20;i++){
            System.out.println(Thread.currentThread().getName()+"运行……"+i);
        }
    }
}

public class ThreadJoinDemo {

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Thread t = new Thread(mt);
        t.start();
        for(int i=0;i<30;i++){
            if(i>10){
                try{
                    t.join();
                }catch(Exception e){}
            }
            System.out.println("Main线程"+i);
        }
    }
}

线程的休眠:

sleep为静态方法,使用类名Thread直接调用

 1 class MyThread implements Runnable{
 2     public void run(){
 3         for(int i=0;i<5;i++){
 4             try{
 5                 Thread.sleep(1000);//每次输出都会间隔1000ms,达到延迟操作的结果
 6             }catch(Exception e){}
 7             System.out.println(Thread.currentThread().getName()+"…………"+i);
 8         }
 9     }
10 }
11 
12 public class ThreadSleepDemo {
13 
14     public static void main(String[] args) {
15         MyThread mt = new MyThread();
16         new Thread(mt,"线程").start();
17     }
18 
19 }

线程的中断:

 1 class MyThread implements Runnable{
 2     public void run(){
 3         System.out.println("进入run方法");
 4         try{
 5             Thread.sleep(10000);
 6             System.out.println("已完成休眠");
 7         }catch(Exception e){
 8             System.out.println("休眠被终止");
 9             return;
10         }
11         System.out.println("正常结束");
12     }
13 }
14 
15 public class ThreadInterruptDemo {
16     public static void main(String[] args) {
17         MyThread mt = new MyThread();
18         Thread t = new Thread(mt);
19         t.start();
20         try{
21             Thread.sleep(2000);
22         }catch(Exception e){}
23         t.interrupt();        
24     }
25 }

在使用joinsleep时,要进行异常处理。

线程的礼让:

 1 class MyThread implements Runnable{
 2     public void run(){
 3         for(int i=0;i<5;i++){
 4             System.out.println(Thread.currentThread().getName()+"运行"+i);
 5             if(i==2){
 6                 System.out.print("线程礼让:");
 7                 Thread.currentThread().yield();
 8             }
 9         }
10     }
11 }
12 
13 public class ThreadYieldDemo {
14 
15     public static void main(String[] args) {
16         MyThread mt = new MyThread();
17         Thread t1 = new Thread(mt,"线程A");
18         Thread t2 = new Thread(mt,"线程B");
19         t1.start();
20         t2.start();
21     }
22 }

每当线程满足条件(i=2)时,本线程就会停止,而让其他线程先执行。

同步:指多个操作在同一时间段内只能有一个线程进行,其他线程要等待此线程完成之后才可以继续进行。

解决资源共享的同步操作,可以使用同步代码块和同步方法两种方式完成。

同步代码块:

 1 class MyThread implements Runnable{
 2     private int ticket = 20;
 3     public void run(){
 4         for(int i=0;i<100;i++){
 5             synchronized(this){        //将当前对象(this)设置成同步对象
 6                 if(ticket>0){
 7                     System.out.println(ticket--);
 8                 }
 9             }
10         }
11     }
12 }
13 
14 public class SynchronizedDemo {
15 
16     public static void main(String[] args) {
17         MyThread mt = new MyThread();
18         new Thread(mt).start();
19         new Thread(mt).start();
20         new Thread(mt).start();
21     }
22 }

同步方法:(使用synchronized关键字将一个方法声明为同步方法)

 1 class MyThread implements Runnable{
 2     private int ticket = 50;
 3     public void run(){
 4         for(int i=0;i<100;i++){
 5             this.sale();
 6         }
 7     }
 8     private synchronized void sale() {
 9             if(ticket>0){
10                 System.out.println(ticket--);
11             }
12     }
13 }
14 
15 public class SynchronizedDemo {
16 
17     public static void main(String[] args) {
18         MyThread mt = new MyThread();
19         new Thread(mt).start();
20         new Thread(mt).start();
21         new Thread(mt).start();
22     }
23 }

Java中方法定义的完整格式:

访问权限(publicdefaultprotectedprivate[final][static][synchronized]

返回值类型 void 方法名称(参数类型,参数名称)[throws Exception1,Exception2]

{

return 返回值;

}

死锁:指两个线程都在等着彼此先完成,造成了程序的停滞。

卖票:同一个动作处理同一资源

生产者消费者:不同动作处理同一资源

 1 class Info{
 2     private String name = "zhangsan";
 3     private String content = "java";
 4     private boolean flag = false;
 5     public synchronized void set(String name,String content){
 6         if(!flag){
 7             try{
 8                 super.wait();
 9             }catch(InterruptedException e){
10                 e.printStackTrace();
11             }
12         }
13         this.name = name;
14         this.content = content;
15         flag = false;
16         super.notify();
17     }
18     public synchronized void get(){
19         if(flag){
20             try{
21                 super.wait();
22             }catch(InterruptedException e){
23                 e.printStackTrace();
24             }
25         }
26         System.out.println(name+ ":" +content);
27         flag = true;
28         super.notify();
29     }
30 }
31 
32 class Producer implements Runnable{
33     private Info info = null;
34     public  Producer(Info info){
35         this.info = info;
36     }
37     public void run(){
38         boolean flag = false;
39         for(int i=0;i<10;i++){
40             if(flag){
41                 this.info.set("zhangsan", "java");
42                 flag = false;
43             }else{
44                 this.info.set("wangzhi","www");
45                 flag = true;    
46             }
47         }
48     }
49 }
50 
51 class Consumer implements Runnable{
52     private Info info = null;
53     public Consumer(Info info){
54         this.info = info;
55     }
56     public void run(){
57         for(int i=0;i<10;i++){
58             try{
59                 Thread.sleep(100);
60             }catch(Exception e){
61                 e.printStackTrace();
62             }
63             this.info.get();
64         }
65     }
66 }
67 
68 public class ThreadCaseDemo {
69 
70     public static void main(String[] args) {
71         Info i = new Info();
72         Producer pro = new Producer(i);
73         Consumer con = new Consumer(i);
74         new Thread(pro).start();
75         new Thread(con).start();
76     }
77 }

停止线程运行:在多线程开发中可以通过设置标志位的方式停止一个线程的运行。

原文地址:https://www.cnblogs.com/XuGuobao/p/7226344.html