您的位置:首页 > 编程语言 > Java开发

Java学习之线程中一些方法,生命周期,线程间通信

2017-05-25 09:31 435 查看

一、线程中的一些方法

1、线程加入

public final void join()

使用这个方法后,其他线程必须要在这个线程执行完之后才能继续抢着执行

public class Test {
public static void main(String[] args) {
//创建线程对象
MyThread mt = new MyThread();
MyThread mt2 = new MyThread();
MyThread mt3 = new MyThread();

//设置线程名字
mt.setName("大宝");
mt2.setName("菲菲");
mt3.setName("张益达");

//开启线程
mt.start();

//线程加入
try {
mt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

mt2.start();
mt3.start();
}
}

2、线程礼让

public static void yield()

暂停当前正在执行的线程对象,并执行其他程序

作用:让线程间的执行更和谐一些,但是实际上做不到

public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(this.getName()+":"+i);
MyThread.yield();
}
}
}

3、线程死亡

public final void stop():直接杀死

public void interrupt();直接杀死,在死前,还可以有遗言

代码:

类:

package com.edu_03;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MyThread extends Thread{
@Override
public void run() {
System.out.println("开始时间"+new SimpleDateFormat("HH:mm:ss").format(new Date()));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("我已经被杀死了");
}
System.out.println("开始时间"+new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
主程序:
package com.edu_03;

public class Test {
public static void main(String[] args) {
//创建线程对象
MyThread mt = new MyThread();

//设置线程名字
mt.setName("大宝");

//开启线程
mt.start();

//再睡觉中杀死
try {
Thread.sleep(3000);
//public final void stop():直接杀死
//mt.stop();
// public void interrupt():直接杀死,在死前,还可以有遗言。
mt.interrupt();
} catch (Exception e) {
// TODO: handle exception
}

}
}

二、线程的生命周期:



三、线程间通信

生产消费者问题不同类型针对同一资源操作
例如:
售票案例:在卖票的同时还要有入票,
买票的窗口可能多个,那么买入票的窗口可能也是多个
案例:
以给学生设置和获取姓名和年龄为例,演示线程通信问题
  线程间通讯:
  资源:Student
  设置数据线程:SetThread
  获取数据线程:GetThread
  测试类:T

代码:
资源:
package com.edu_04;

public class Student {
String name;
int age;
boolean flag;

}
设置数据线程:
package com.edu_04;
//作用:用于给学生对象赋值
//在赋值前利用student对象中自带的flag字段进行判断,如果为true说明已经赋了值则让这个线程等待,从而让获取值得线程运行
//如果为false则说明没有赋值,则执行下面的判断代码,然后进行赋值,赋值之后吧flag赋值为true,然后唤醒其他等待的代码
public class SetThread implements Runnable{

private Student s;
private int i= 0;
//有参构造
public SetThread(Student s){
this.s = s;
}

@Override
public void run() {
while (true) {
synchronized (s) {
if (s.flag) {//如果flag为true则等待
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (i%2==0) {
s.name = "周杰伦";
s.age = 35;
}else{
s.name = "汪峰";
s.age = 45;
}
i++;

s.flag=true;//把flag赋值为true
s.notify();//唤醒线程,如果有等待的线程则唤醒,如果没有则什么也没有
}
}

}
}
获取线程资源:
package com.edu_04;
//作用:输出值
//先进行判断,如果为false则等待,如果为true则执行下面的代码输出值,同时把flag赋值为false,然后唤醒其他等待的代码
public class GetThread implements Runnable{
private Student s;

public GetThread(Student s){
this.s = s;
}

@Override
public void run() {
while (true) {
synchronized (s) {
if(!s.flag){//如果flag为false则等待
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

System.out.println(s.name+":"+s.age);

s.flag = false;
s.notify();
}
}
}
}
测试类:
package com.edu_04;

public class Test {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();

//创建线程对象
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
Thread sd = new Thread(st);
Thread gd = new Thread(gt);

//开启线程
sd.start();
gd.start();
}
}
为了让设置线程和获取纤尘操作的是同一个资源,把学生对象作为构造参数传了过去,
为了防止初夏线程安全问题,我们加了同一把锁(就是这个传递的参数),为了实现礼让效果,我们加了等待唤醒机制
还可以优化的是把同步代码块改为同步方法,在类中实现:
package com.edu_05;
/**
* 使用同步方法代替代码块
*
*/
public class Student {
private String name;
private int age;
private boolean flag;

public synchronized void setThread(String name,int age){
synchronized (this) {
if (this.flag) {//如果flag为true则等待
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
this.age = age;

this.flag=true;//把flag赋值为true
this.notify();//唤醒线程,如果有等待的线程则唤醒,如果没有则什么也没有
}
}

public synchronized void getThread(){
synchronized (this) {
if(!this.flag){//如果flag为false则等待
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();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: