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(); } } }
相关文章推荐
- java线程基础巩固---Thread中断Interrupt方法学习&采用优雅的方式结束线程生命周期
- JAVA基础 day12 线程间通信 多线程一些常用方法
- java线程学习-thread的一些方法
- JAVA多线程学习3--线程一些方法
- Java基础学习__多线程(线程间通信--生产者消费者JDK5.0升级版)
- java基础学习__多线程(停止线程,守护线程,join方法)
- Java基础学习6_多线程(线程间通信--生产者消费者)
- Java基础学习5_多线程(线程间通信--等待唤醒机制)
- java学习日记(5)——创建线程的两种基本方法
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
- Java学习笔记(线程间通信)
- Java 多线程(七) 线程间的通信——wait及notify方法
- java线程学习5——线程同步之同步方法
- java学习之路——线程3(线程之间的通信)
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
- Java核心知识点学习----使用Condition控制线程通信
- Java学习笔记42:线程的几个方法和概念
- java学习之创建线程方法二
- 学习java多线程的笔记3-使用BlockingQueue阻塞队列来模拟两个线程之间的通信
- 线程入门学习3-------线程的生命周期和常用方法