第一节 多线程的了解
定义:同时对多项任务的引入
感觉自己的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 block
e.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 希望大佬可以
来指点~