java基础10(多线程2)

Posted

tags:

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

  1. 线程的常用方法

       public final void join()    线程加入

  作用:等待该线程中止,其他线程才能继续抢着执行

       public static void yield():  线程礼让

  作用:暂停当前正在执行的线程对象,并执行其他线程。让线程间的执行更和谐一些,但是实际上做不到。

       public final void stop():线程死亡:直接杀死

       public void interrupt():线程死亡:直接杀死,在死前,还可以有遗言(会执行后面的代码,然后死去)。

      static void sleep(long millis)  线程休眠:线程睡一会,会自己醒来

2.线程的生命周期

   a.新建:创建一个线程对象

   b.就绪:start()之后,有cpu的执行权,但没有抢到执行资格

   c.运行:有cpu的执行权,也有cpu的执行资格

   d.有可能阻塞:休眠或者等待

   e.死亡:run()方法执行完毕,调用stop()或者interrup()方法

 生命周期图如下:

技术分享

3.线程间通信

   定义:不同线程间针对同一个资源进行操作


   Student -- 被设置的资源对应的类

   setThread -- 设置线程

   getThread -- 获取线程

   StudnetDemo -- 测试类


public class Student {

private String name;

private int age;

//作为对象的一个标记,如果是false说明该对象没有数据

private boolean flag;

//提供公共的方法设置信息

public synchronized void setInfo(String name,int age){

if (this.flag) {

//等待

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//没有值的话,在这里给对对象设置数据

this.name = name;

this.age = age;

//更改标记,唤醒获取线程获取数据

this.flag = true;

this.notify();

}

//提供公共的方法获取信息

public synchronized void getInfo(){

if (!this.flag) {

//没有值

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//有数据,取数据

System.out.println(this.name+"--"+this.age);

//取完数据之后,就没有数据了

this.flag = false;

this.notify();

}

}


public class GetThread implements Runnable{

private Student s;

public GetThread(Student s){

this.s = s;

}

@Override

public void run() {

//获取线程,获取学生对象的姓名和年龄

while (true) {

s.getInfo();

}

}

}

}



public class SetThread implements Runnable{

private Student s;

private int x=0;

public SetThread(Student s){

this.s = s;

}

@Override

public void run() {

//给学生对象设置姓名和年龄

while (true) {

if (x%2==0) {

s.name = "周杰伦";

s.age = 40;

}else {

s.name = "林宥嘉";

s.age = 30;

}

x++;

}

}

}

public class StudentDemo {

public static void main(String[] args) {

//创建学生对象

Student s = new Student();

//创建设置线程和获取线程

SetThread st = new SetThread(s);

GetThread gt = new GetThread(s);

Thread t1 = new Thread(st);

Thread t2 = new Thread(gt);

//开启线程

t1.start();

t2.start();

}


}

4.线程组

  定义:Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。默认情况下,所有的线程都属于主线程组。

  主要方法:

   public final ThreadGroup getThreadGroup():获取线程对应的线程组对象

  

   Thread(ThreadGroup group, Runnable target):线程设置分组 


案例1:创建线程获取对应的线程组对象,并获取名称

//创建两个线程

                MyThread mt1 = new MyThread();

MyThread mt2 = new MyThread();

//获取上面两个线程对应的线程组对象

ThreadGroup tg1 = mt1.getThreadGroup();

ThreadGroup tg2 = mt2.getThreadGroup();

//获取线程组对象的名称

System.out.println(tg1.getName());

System.out.println(tg2.getName());

案例2:创建线程组对象,给线程分配线程组


ThreadGroup tg = new ThreadGroup("big");

Thread t3 = new Thread(tg, new MyRunnable());

Thread t4 = new Thread(tg, new MyRunnable());

//获取t3和t4的线程组对象

ThreadGroup tg3 = t3.getThreadGroup();

ThreadGroup tg4 = t4.getThreadGroup();

System.out.println(tg3.getName());

System.out.println(tg4.getName());


5.线程池

    引入原因:程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。

    特点:线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。

    线程池的创建方法:

    public static ExecutorService newFixedThreadPool(int nThreads)

  线程池的使用步骤:

  a.创建线程池对象

   ExecutorService pool = Executors.newFixedThreadPool(2);


  b.创建Runnable实例

  MyRunnable my = new MyRunnable();


  c.提交Runnable实例

   pool.submit(my);

   pool.submit(my);


   d.关闭线程池

   pool.shutdown();


6.定时器(Timer):

   主要方法:

   public Timer()构造

   public void schedule(TimerTask task, long delay)延迟多久执行任务

   public void schedule(TimerTask task,long delay,long period)延迟多久执行任务,并以后每隔多久执行一次

   public boolean cancel()取消这个任务


   TimerTask

   public abstract void run()放的是所要执行的任务代码


案例:延迟5秒钟,打印hellojava,以后每隔一秒打印一次

public static void main(String[] args) {

Timer t = new Timer();

t.schedule(new MyTimerTask2(), 5000, 1000);

/**

* 参数1:要执行的任务

* 参数2:延迟多久执行

* 参数3:执行一次之后,每隔多久重复执行

*/

}


}


class MyTimerTask2 extends TimerTask{

@Override

public void run() {

System.out.println("hellojava");

}

}


以上是关于java基础10(多线程2)的主要内容,如果未能解决你的问题,请参考以下文章

java基础第八天_多线程

java基础第八天_多线程

java 基础--多线程基础练习

多线程(模拟买票)-----java基础知识总结

Java多线程系列---“基础篇”10之 线程优先级和守护线程

IT十八掌作业_java基础第九天_多线程自动拆装箱