Java线程

来源:互联网 发布:淘宝联盟钱多久返利 编辑:程序博客网 时间:2024/05/16 05:51

java多线程学习


一、什么是线程?什么是进程?两者又有什么区别?

这里写图片描述

二、线程的状态有哪些?

这里写图片描述


三、线程的实现

这里写图片描述

注意,当用start()实现多线程的时候,线程会实现并发执行,也就是那个线程抢到了cpu那个就执行。如果用run()方法,那就是线程1执行完之后才会只能线程2,就不会有并发。

3.1,使用继承Thread方法,实现三个线程并发

  • 代码线程工具类实现
public class ThreadUtil extends Thread {        public String names;        public ThreadUtil(String name) {            super();            names = name;        }        //写一个构造方法,来接通主类        @Override        public void run() {            for (int i = 0; i < 5; i++) {                System.out.println(names+" :次数 "+i);            }        }}
  • 引用类
public class MyThread {    public static void main(String[] args) {        ThreadUtil tu1 = new ThreadUtil("我是线程tu1");        ThreadUtil tu2 = new ThreadUtil("我是线程tu2");        ThreadUtil tu3 = new ThreadUtil("我是线程tu3");        tu1.start();        tu2.start();        tu3.start();    }}
  • 打印结果:
    这里写图片描述

3.2,使用Runnable接口

  • Runnable工具类
public class MyRunnable implements Runnable{    public String names;    public MyRunnable(String name) {        super();        names = name;    }    //写一个构造方法,来接通主类    @Override    public void run() {        for (int i = 0; i < 5; i++) {            System.out.println(names+" :次数 "+i);        }    }}

-主类引用

public class MyThread {    public static void main(String[] args) {        MyRunnable tu1 = new MyRunnable("我是实现Runnable的线程tu1");        MyRunnable tu2 = new MyRunnable("我是实现Runnable线程tu2");        MyRunnable tu3 = new MyRunnable("我是实现Runnable线程tu3");        //切记这里不能直接,tu1.start()。你需要创建一个Thread对象来接受我们实现的线程对象        Thread tr1 = new Thread(tu1);        tr1.start();        Thread tr2 = new Thread(tu2);        tr2.start();        Thread tr3 = new Thread(tu3);        tr3.start();    }}
  • 运行结果:成功:
    这里写图片描述

四、线程的常用方法

这里写图片描述

4.1代码来验证这些方法

  • 代码模块:
public class TextRunnable{    public static void main(String[] args) {        TextRunnables trR = new TextRunnables("线程名称");        Thread td1 = new Thread(trR);        //来验证是否启动状态        System.out.println("线程的状态1:"+td1.isAlive());        td1.start();        System.out.println("线程的状态2:"+td1.isAlive());        //下面代码含义在于测试线程的join()强制执行的方法            for (int i = 0; i < 20; i++) {            //在主线程写一个循环,执行20次,然后当主线程执行到10的时候,强制执行子线程。如下            if (i==10) {                try {                    td1.join();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            System.out.println("主线程:"+i);        }    }    static class TextRunnables implements Runnable{            public String names;            public TextRunnables(String name) {                names = name;            }            //写一个构造方法,来接通主类            @Override            public void run() {                for (int i = 0; i < 5; i++) {                    //获取线程的名称                    System.out.println("线程名称: "+Thread.currentThread().getName());                }            }     }}
  • 1、获取线程的名称
`System.out.println("线程名称: "+Thread.currentThread().getName());
  • 2、判断线程是否启动
TextRunnables trR = new TextRunnables("线程名称");        Thread td1 = new Thread(trR);        //来验证是否启动状态        System.out.println("线程的状态1:"+td1.isAlive());//打印是未启动        td1.start();        System.out.println("线程的状态2:"+td1.isAlive());//打印已经未启动
  • 3、验证强制开启子线程join()方法
//下面代码含义在于测试线程的join()强制执行的方法            for (int i = 0; i < 20; i++) {            //在主线程写一个循环,执行20次,然后当主线程执行到10的时候,强制执行子线程。如下            if (i==10) {                try {                    td1.join();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            System.out.println("主线程:"+i);        }    }
  • 剩下的还有睡眠sleep(),还有一个礼让方法yieid()方法,这里就不说了。
  • -

四、线程的优先级

这里写图片描述

代码模块

public class MyRunnable02 {     public static void main(String[] args) {         //然后我们创建三个线程。来引用线程的优先级         Thread t1 = new Thread(new TextRunnables(),"A");         Thread t2 = new Thread(new TextRunnables(),"B");         Thread t3 = new Thread(new TextRunnables(),"C");         //设置优先级         t1.setPriority(Thread.MAX_PRIORITY);         t2.setPriority(Thread.MIN_PRIORITY);         t3.setPriority(Thread.NORM_PRIORITY);         //开启线程         t1.start();         t2.start();         t3.start();        }        static class TextRunnables implements Runnable{                //写一个构造方法,来接通主类                @Override                public void run() {                    for (int i = 0; i < 5; i++) {                        //获取线程的名称                        try {                            Thread.sleep(1000);                            System.out.println("线程名称: "+Thread.currentThread().getName()+i);                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    }                }         }    }

结果分析:优先级高,提高的是占CPU的效率,而非就一定谁的高就必须先执行


  • 这里写图片描述

五、线程的同步

这里写图片描述

5.1:什么时候需要用到同步呢? 就是程序的资源需要给多个线程共享的时候,打个比方,火车站有5张车票 ,三个人去抢。如果没有任何管理的情况下,就会出现有人付过钱了但是没有获得票的结局。例如下方代码

public class MyRunnable02 {     public static void main(String[] args) {         //然后我们创建三个线程。来引用线程的优先级         TextRunnables fRunnables = new TextRunnables();         Thread t1 = new Thread(fRunnables);         Thread t2 = new Thread(fRunnables);         Thread t3 = new Thread(fRunnables);         //开启线程         t1.start();         t2.start();         t3.start();        }        static class TextRunnables implements Runnable{                //假设有五张牌                private int ticket = 5;                @Override                public void run() {                        for (int i = 0; i < 10; i++) {                            //如果还有票就继续抢                            if(ticket>0){                            //获取线程的名称                            try {                                //睡眠500毫秒抢一次                                Thread.sleep(500);                              } catch (InterruptedException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                            }                            //如果被抢走,就减少一张票数量                            System.out.println("车票剩余: "+ticket--);                        }                    }                }         }    }

运行结果

这里写图片描述

5.2:所以我们就要用到同步(synchronized)来分配资源,这样就好比有一个专门的售票员一样,一手交钱一手交货, 相比5.1中,也就是在处理车票数据的时候添加一个同步锁

public class MyRunnable02 {     public static void main(String[] args) {         //然后我们创建三个线程。来引用线程的优先级         TextRunnables fRunnables = new TextRunnables();         Thread t1 = new Thread(fRunnables);         Thread t2 = new Thread(fRunnables);         Thread t3 = new Thread(fRunnables);         //开启线程         t1.start();         t2.start();         t3.start();        }        static class TextRunnables implements Runnable{                //假设有五张牌                private int ticket = 5;                @Override                public void run() {                    //加一个同步代码块,这样就可以合理的分配资源,不会出现cpu抢占资源问题                    synchronized (this) {                        for (int i = 0; i < 10; i++) {                            //如果还有票就继续抢                            if(ticket>0){                            //获取线程的名称                            try {                                //睡眠500毫秒抢一次                                Thread.sleep(500);                              } catch (InterruptedException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                            }                            //如果被抢走,就减少一张票数量                            System.out.println("车票剩余: "+ticket--);                        }                    }                    }                }         }    }

运行结果

这里写图片描述


5.3:我们上面5.2用的是同步代码块,那我们用同步方法如何实现的,其实很简单,只需要声明一个同步的方法即可。如下:

public class MyRunnable02 {     public static void main(String[] args) {         //然后我们创建三个线程。来引用线程的优先级         TextRunnables fRunnables = new TextRunnables();         Thread t1 = new Thread(fRunnables);         Thread t2 = new Thread(fRunnables);         Thread t3 = new Thread(fRunnables);         //开启线程         t1.start();         t2.start();         t3.start();        }        static class TextRunnables implements Runnable{                //假设有五张牌                private int ticket = 5;                @Override                public void run() {                    //直接调用同步方法即可                     tell();                }                //写一个同步的方法                public synchronized void tell(){                    for (int i = 0; i < 10; i++) {                        //如果还有票就继续抢                        if(ticket>0){                        //获取线程的名称                        try {                            //睡眠500毫秒抢一次                            Thread.sleep(500);                          } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                        //如果被抢走,就减少一张票数量                        System.out.println("车票剩余: "+ticket--);                    }                }                }         }    }

运行结果:也是正确的运行,只是处理同步资源的时候,放在一个同步方法中去处理

这里写图片描述


六、什么是死锁?

打个比方,一对情侣,女方必须要求南方在北京买一套3000万的房子,男子缺必须在老家买个30万的别墅。两个人就开始相互争执,这就造成了问题的无法解决,就可以理解为死锁。解决的办法,就是双方的某一方,降低自己的要求,能使两者都接受就可以了。

七、线程的生命周期?

这里写图片描述

就那么多把。都是最基础的。想深入了解的小伙伴可以i多搜搜这方面的知识!特别是线程同步多多注意

0 0