一、线程的常用方法
1.1 方法的介绍
定义一个线程类
package qf22020309_consumer_producer;
public class MyThread01 extends Thread {
@Override
public void run ( ) {
for ( int i = 0 ; i < 100 ; i++ ) {
System. out. println ( Thread. currentThread ( ) . getName ( ) + " " + i) ;
}
}
}
1.2 stop终止该线程
package qf22020309_consumer_producer;
public class Demo01 {
public static void main ( String[ ] args) {
MyThread01 mt1 = new MyThread01 ( ) ;
mt1. start ( ) ;
mt1. stop ( ) ;
MyThread01 mt2 = new MyThread01 ( ) ;
mt2. start ( ) ;
}
}
1.2 join等待线程执行完终止
package qf22020309_consumer_producer;
public class Demo03 {
public static void main ( String[ ] args) throws InterruptedException {
MyThread03 mt1 = new MyThread03 ( ) ;
mt1. start ( ) ;
mt1. join ( ) ;
MyThread03 mt2 = new MyThread03 ( ) ;
mt2. start ( ) ;
}
}
1.3 yield礼让线程
package qf22020309_consumer_producer;
public class Demo02 {
public static void main ( String[ ] args) {
MyThread02 mt1 = new MyThread02 ( ) ;
mt1. yield ( ) ;
mt1. start ( ) ;
MyThread02 mt2 = new MyThread02 ( ) ;
mt2. start ( ) ;
}
}
二、Object提供wait()等线程操作-生产者与消费者模式设计
2.1 方法的介绍
2.2 案例应用
问题:生产者做一个米饭,必须等待消费者吃完才能继续生产,而消费者必须等待生产者生产出来才能吃饭 rice米饭对象
package qf22020309_work. Demo04;
public class Rice {
private String money;
private String weight;
private Boolean flag = false ;
public Rice ( ) {
}
public Rice ( String money, String weight) {
this . money = money;
this . weight = weight;
}
public String getMoney ( ) {
return money;
}
public void setMoney ( String money) {
this . money = money;
}
public String getWeight ( ) {
return weight;
}
public void setWeight ( String weight) {
this . weight = weight;
}
public Boolean getFlag ( ) {
return flag;
}
public void setFlag ( Boolean flag) {
this . flag = flag;
}
@Override
public String toString ( ) {
return "Rice{" +
"money='" + money + '\'' +
", weight='" + weight + '\'' +
", flag=" + flag +
'}' ;
}
}
生产者
package qf22020309_work. Demo04;
public class MyProducer extends Thread {
private Rice rice;
public MyProducer ( Rice rice) {
this . rice = rice;
}
@Override
public void run ( ) {
while ( true ) {
synchronized ( rice) {
try {
Thread. sleep ( 2500 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
if ( rice. getFlag ( ) ) {
try {
rice. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
rice. setMoney ( "12元" ) ;
rice. setWeight ( "5两米饭" ) ;
rice. setFlag ( true ) ;
System. out. println ( "我在做着" + rice. getMoney ( ) + ",重" + rice. getWeight ( ) + "的米饭" ) ;
rice. notify ( ) ;
}
}
}
}
消费者
package qf22020309_work. Demo04;
public class MyConsumer extends Thread {
private Rice rice;
public MyConsumer ( Rice rice) {
this . rice = rice;
}
@Override
public void run ( ) {
while ( true ) {
synchronized ( rice) {
try {
Thread. sleep ( 2500 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
if ( ! rice. getFlag ( ) ) {
try {
rice. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System. out. println ( "我在吃" + rice. getMoney ( ) + ",重" + rice. getWeight ( ) + "的米饭" ) ;
rice. setMoney ( null) ;
rice. setWeight ( null) ;
rice. setFlag ( false ) ;
rice. notify ( ) ;
}
}
}
}
测试类
package qf22020309_work. Demo04;
public class Test01 {
public static void main ( String[ ] args) {
Rice rice = new Rice ( ) ;
new MyProducer ( rice) . start ( ) ;
new MyConsumer ( rice) . start ( ) ;
}
}
2.3 生产者与消费者设计总结
wait()方法是让自身的线程等待,给其它的线程(需锁的相同对象)有抢夺cpu的执行权的权力 notify是通知此监听器(相同对象)对象上等待的单个线程执行,notifyAll是通知此监听器(相同对象)对象上等待的全部线程执行 案例总结: 该案例没有使用资源共享,而只使用了synchronized锁的对象 两者锁的对象相同,消费者必须等待生产者生产出来了才能吃饭,这个等待时间是无限的,所以使用wait(),礼让等待生产者线程生产,生产者相同 等待生产者做好了,再发通知,消费者相同,所用使用notify() 必须锁的相同的对象
三、枚举
3.1 概念
枚举就是用于表示一些固定的值,可以使用枚举项类进行 访问修饰 enum 枚举类的名称{ 枚举项
}
3.2 特点
每一个枚举类都是Enum的子类 每一个枚举项都是一个对象 枚举类只能有私有的构造 枚举项一般都是写在第一行,每个枚举项必须重写本类中的抽象方法,可以定义成员变量
package qf22020309_enum. Demo01;
public enum MyEnum {
re {
@Override
public void add ( ) {
}
} , rs {
@Override
public void add ( ) {
}
} ;
private String name;
public String name1;
MyEnum ( ) {
}
private MyEnum ( String name, String name1) {
this . name = name;
this . name1 = name1;
}
public static void get ( ) {
}
public void get1 ( ) {
}
public abstract void add ( ) ;
}
四、线程的声明周期
4.1 线程状态图
线程的生命周期有几种状态 获取状态:Thread.State
4.2 6种状态
NEW:至今尚未启动的线程 RUNNABLE:正在java虚拟机中执行的线程 BLOCKED:受阻塞并等待某个监视器锁的线程 WAITING:无限期的等待另一个线程去执行操作的线程 TIMED_WAITING:等待另一个线程去执行,取决于指定等待的时间的线程 TERMINATED:已退出的线程处于这种状态
package qf22020308_thread. Demo03;
public class Demo02 {
public static void main ( String[ ] args) {
Thread thread = new Thread ( ) ;
System. out. println ( thread. getState ( ) ) ;
thread. start ( ) ;
System. out. println ( thread. getState ( ) ) ;
}
}
五、线程池
5.1 简介
没有线程池的问题:A.需要反复的创建销毁 B.大量的的线程不便于管理 C.遭到破坏性较大的的任务,可能会导致线程任务失败 线程池:A.jdk提供的线程池,可以使用线程池来的对线程进行统一的管理 B. 避免反复的创建和销毁 C. 遇到破坏性较大的任务时,线程任务执行失败后,线程池会重新派线程去执行为,确保任务的执行操作
5.2 创建线程池对象的方法
Executors 线程工具类调用 调用单一线和多线程对象获取方法图 提交任务有返回值和无返回值
5.2 案例
单一线程有返回值-代码实例
package qf22020309_ThreadPool. Demo01;
import java. util. concurrent. Callable;
public class MyCallable implements Callable < Integer> {
@Override
public Integer call ( ) throws Exception {
return 520 ;
}
}
package qf22020309_ThreadPool. Demo01;
import java. util. concurrent. *;
public class Test01 {
public static void main ( String[ ] args) throws ExecutionException, InterruptedException {
MyCallable mc = new MyCallable ( ) ;
ExecutorService es = Executors. newSingleThreadExecutor ( ) ;
Future< Integer> submit = es. submit ( mc) ;
System. out. println ( submit. get ( ) ) ;
}
}
多线程无返回值-代码实例
package qf22020309_ThreadPool. Demo02;
public class MyRunnable implements Runnable {
@Override
public void run ( ) {
System. out. println ( "runnable" ) ;
}
}
package qf22020309_ThreadPool. Demo02;
import java. util. concurrent. ExecutionException;
import java. util. concurrent. ExecutorService;
import java. util. concurrent. Executors;
import java. util. concurrent. Future;
public class Test02 {
public static void main ( String[ ] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors. newFixedThreadPool ( 3 ) ;
es. submit ( new MyRunnable ( ) ) ;
es. submit ( new MyRunnable ( ) ) ;
es. submit ( new MyRunnable ( ) ) ;
es. submit ( new MyRunnable ( ) ) ;
}
}
六、单例设计模式
单例设置模式的特点:有且仅实例化一个对象 使用场景:加载配置信息、工具类、spring、容器对象等 私有属性、私有构造方法、公有的方法
6.1 懒汉设计模式
优点:项目启动时,不可能出现卡顿现象 缺点:没有锁的机制,多线程不安全 定义类
package qf22020309_design. Demo01;
public class MyDesign {
private static MyDesign md;
private MyDesign ( ) {
}
public static MyDesign getInstance ( ) {
if ( md == null) {
md = new MyDesign ( ) ;
}
return md;
}
}
测试类
package qf22020309_design. Demo01;
public class Demo01 {
public static void main ( String[ ] args) {
System. out. println ( MyDesign. getInstance ( ) ) ;
System. out. println ( MyDesign. getInstance ( ) ) ;
}
}
6.2 饿汉设计模式
优点:没有锁的机制、效率比较高 缺点:项目启动时就创建对象,项目可能会出现卡顿,多线程不安全 定义类
package qf22020309_design. Demo02;
public class MyDesign {
private static MyDesign p = new MyDesign ( ) ;
private MyDesign ( ) { } ;
public static MyDesign getInstance ( ) {
return p;
}
}
测试类
package qf22020309_design. Demo02;
public class Demo01 {
public static void main ( String[ ] args) {
System. out. println ( MyDesign. getInstance ( ) ) ;
System. out. println ( MyDesign. getInstance ( ) ) ;
}
}
6.3 双重锁设计模式
代码实例
package qf22020309_design. Demo04;
public class Utils {
private static Utils utils;
private Utils ( ) {
}
public static synchronized Utils GetInstance ( ) {
if ( utils== null) {
synchronized ( Utils. class ) {
if ( utils== null) {
return utils = new Utils ( ) ;
}
}
}
return utils;
}
}
6.4 内部类模式
package qf22020309_design. Demo04;
public class Utils {
private Utils ( ) {
}
static class Instance {
static final Utils UTILS = new Utils ( ) ;
}
public static Utils getInstance ( ) {
return Instance. UTILS;
}
}
七、定时器
7.1 设计定时读取文件的内容
自定义类
package qf22020309_work. Demo01;
import java. io. *;
import java. util. TimerTask;
public class MyTask extends TimerTask {
@Override
public void run ( ) {
InputStreamReader isr = null;
try {
isr = new InputStreamReader ( new FileInputStream ( "D:\\test.txt" ) ) ;
int temp;
char [ ] ch = new char [ 1024 * 1024 ] ;
while ( ( temp= isr. read ( ch) ) != - 1 ) {
System. out. print ( new String ( ch, 0 , temp) ) ;
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
} finally {
try {
if ( isr!= null) {
isr. close ( ) ;
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
}
测试类
package qf22020309_work. Demo01;
import java. text. ParseException;
import java. text. SimpleDateFormat;
import java. util. Date;
import java. util. Scanner;
import java. util. Timer;
public class Demo01 {
public static void main ( String[ ] args) throws ParseException {
MyTask mt = new MyTask ( ) ;
Timer t = new Timer ( ) ;
Scanner sc = new Scanner ( System. in) ;
System. out. println ( "请输入读取文件的时间:" ) ;
SimpleDateFormat sdf = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
Date parse = sdf. parse ( sc. nextLine ( ) ) ;
t. schedule ( mt, parse) ;
}
}