JAVA多线程引入(8)

来源:互联网 发布:js 新建json对象 编辑:程序博客网 时间:2024/06/07 22:25

第一节 多线程的了解

定义:同时对多项任务的引入

感觉自己的eclipse的字体不舒服  大家可以看这个博客   讲的很清楚  字体也非常好用    点击打开链接

其实线程的概念非常常用  基本的概念就是同时干多件事情 最常规的理解就是为什么在打开以随时点击里一个窗口时可以随时

点击里面的一些摁钮而会立即得到响应  就是有一个线程一直在等待 当被点击时会立即作出反应

下面是一个多线程使用的基本作用

public class no1 {private static void music(){for (int i=0;i<1000;i++)System.out.println("tingyinyue");} private static void eat(){for (int i=0;i<1000;i++)System.out.println("chifan");} public static void main(String[] args) {//music();//eat();no2 musicthread = new no2();no3 eatthread = new no3();musicthread.start();eatthread.start();}}
上面是调用方法,下面是两个线程类

public class no2 extends Thread{public void run(){for (int i=0;i<1000;i++){try{Thread.sleep(100);System.out.println("听音乐");}catch(InterruptedException e){e.printStackTrace();}}}}public class no3 extends Thread{public void run(){for (int i = 0;i<1000;i++)try{Thread.sleep(100);System.out.println("吃饭饭");}catch(InterruptedException e){e.printStackTrace();}}}

不难看出,这样的运行结果


所以我们对多线程有了初步的认识。


第二节 java多线程的实现

在JAVA中多线程有两种实现方式这个大家都知道,下面来介绍

第一种就是继承Thread类:

public class no1 extends Thread{private String threadname;private int baozi = 1;public no1(String t){super();this.threadname = t;}public void run(){while(baozi<=10){System.out.println(threadname+" eat "+baozi+" ball");baozi++;}}public static void main(String[] args) {no1 t1 = new no1("tnny");no1 t2 = new no1("juddy");t1.start();t2.start();}}

这样的运行方式就是很常见的


第二种就是实现接口的方式,实现Runable类

public class no1 implements Runnable{private String threadname;private int baozi = 1;public no1(String t){super();this.threadname = t;}public void run(){while(baozi<=10){System.out.println(threadname+" eat "+baozi+" ball");baozi++;}}public static void main(String[] args) {no1 t1 = new no1("tnny");no1 t2 = new no1("juddy");Thread t11 = new Thread(t1);Thread t22 = new Thread(t2);t11.start();t22.start();}}

和上面的结果一样。不知道到了这里大家会不会跟我有一样的想法,就是如果他们了两个不是分别一个人吃了10个包子,而是

抢10个包子吃呢?

下面就是这个实现,这种抢包子的方式可以用Thread类来实现,因为有共享资源的能力这个类

public class no1 implements Runnable{private String threadname;private int baozi = 1;public no1(String t){super();this.threadname = t;}public synchronized void run(){while(baozi<=10){System.out.println(threadname+" eat "+baozi+" ball");baozi++;}}public static void main(String[] args) {no1 t1 = new no1("super tnny");Thread t11 = new Thread(t1);Thread t12 = new Thread(t1);Thread t13 = new Thread(t1);t11.start();t12.start();t13.start();}}

它的运行结果是super tnny从第一个包子吃到第10个 但是实际上是三个线程在吃包子   在这里要注意到
public synchronized void run()

方法里面的这个

synchronized

关键字,这个的意思是保证不能有两个线程同时进入一个方法内部,保证了吃完一个之后在吃另外一个。


第三节 线程的状态

线程创建之后是不会直接运行的,大家要注意。线程有四个状态,简单按照我的理解就是:

1、新建状态:这个状态就是线程对象刚刚new出来,此时线程并不会运行。

2、就绪状态:新建好的线程经过调用start()方法之后,相当于已经启动了。

3、运行状态:顾名思义,线程开始执行了(自动调用线程的run方法)

4、阻塞状态:1)条件不足2)人为挂起

5、死亡状态:线程调用stop方法或者run方法执行完毕


第四节 线程的常用方法

1、currentThread()和getName()这两个方法前者是返回当前线程,后者是返回线程的名称

public class no1 implements Runnable{public void run(){for (int i =0;i<10;i++){//获取当前线程Thread t=Thread.currentThread();System.out.println(t.getName());//返回线程名称}}public static void main(String[] args) {no1 th = new no1();Thread t1 = new Thread(th,"th1");Thread t2 = new Thread(th,"th2");t1.start();t2.start(); }}

2、isAlive()测试当前线程是不是活跃状态

测试直接将上面代码更改main方法

public static void main(String[] args) {no1 th = new no1();Thread t1 = new Thread(th,"th1");System.out.println("t1 是否活动"+t1.isAlive());t1.start();System.out.println(t1.isAlive());}

3、sleep()线程休眠

这个就是按照ms来计算休眠时间的,这个是静态方法,直接用类名来调用。放在线程前面  要注意需要用到异常处理

public void run(){for (int i =0;i<10;i++){try {Thread.sleep(100);//获取当前线程Thread t=Thread.currentThread();System.out.println(t.getName());//返回线程名称} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

4、setPriority()设置优先级

public static void main(String[] args) {no1 th = new no1();Thread t1 = new Thread(th,"th1");Thread t2 = new Thread(th,"th2");Thread t3 = new Thread(th,"th3");t1.setPriority(Thread.MAX_PRIORITY);t2.setPriority(Thread.MIN_PRIORITY);t3.setPriority(Thread.NORM_PRIORITY);t1.start();t2.start();t3.start();}

5、yield()当前线程强制让出CPU

public class no1 implements Runnable{public void run(){for (int i =0;i<10;i++){//获取当前线程Thread t=Thread.currentThread();System.out.println(t.getName());//返回线程名称if(i ==5){System.out.println("go out!!!");Thread.currentThread().yield();}}}public static void main(String[] args) {no1 th = new no1();Thread t1 = new Thread(th,"th1");Thread t2 = new Thread(th,"th2");t1.setPriority(2);t2.setPriority(1);t1.start();t2.start();}

6、join()和interrupt()以及wait,wake等方法大家自己了解。


第五节 线程的同步


线程的同步存在一些问题,首先就是如果我们写下面这个吃包子的java代码

public class no1 implements Runnable{private int baozi = 10;public void run(){while (baozi > 0){System.out.println(Thread.currentThread().getName()+"吃了第"+baozi+"个包子");baozi--;}}public static void main(String[] args) {no1 th = new no1();Thread t1 = new Thread(th,"张三");Thread t2 = new Thread(th,"李四");t1.start();t2.start();}}

很明显,我们的运行结果是可能有两个人同时吃了第N个包子,所以说我们要保证同步的问题。方法就是同步关键字sychronized

这个关键字有两种用法:

第一种直接加载run方法前面:

public synchronized void run(){while (baozi > 0){System.out.println(Thread.currentThread().getName()+"吃了第"+baozi+"个包子");baozi--;}

第二种就是可以作为一个方法函数:

public void run(){synchronized (this) {while (baozi > 0){System.out.println(Thread.currentThread().getName()+"吃了第"+baozi+"个包子");baozi--;}}}

这样就可以保证不会出现两个人吃同一个包子的结果了。


自己写的这个线程的知识只是线程入门级的东西。只是讲了语法上的比较浅显的东西。还有好多高深的东西现在没有提及,

等之后在用到的时候会在以后的章节博客中给出。谢谢大家,同时也推荐一篇博客园的大佬的线程高级理解和一些厉害的

东西。哈哈。

点击打开链接就是这个连接,最后新人,小菜鸟  希望大家有什么说的不对的能够批评指正~  815884631QQ   希望大佬可以

来指点~

0 0