Java进阶总结——线程
1.进程
/**
* java中启动进程的两种方式
* 1.RunTime,运行时类
* 2.ProcessBuilder类
* */
package day24.process;
import java.io.IOException;
public class ProcessDemo {
public static void main(String[] args) throws IOException {
/*//1通过运行时类
Runtime time=Runtime.getRuntime();
//执行要打开的进程
time.exec("notepad");
time.exec("D:\\TSBrowserDownloads\\cmder\\Cmder.exe");
*/
//2通过进程生成器启动进程
ProcessBuilder builder=new ProcessBuilder("notepad");
//启动进程
builder.start();
}
}
运行结果:
启动应用程序!
2.线程的实现
2.1继承Thread
/**
* ThreadDemo继承了Thread
* 你什么该类就是一个线程类
* 必须在子类中重写run方法
* run方法是线程体
* * */
package day24.thread;
public class ThreadDemo extends Thread{
@Override
public void run() {
// 线程体
try {
Thread.sleep(1000);//休眠1s
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//获取线程名称
System.out.println(Thread.currentThread().getName());
}
public static void method() {
//获取当前线程
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
// 1.获取当前线程
Thread th=Thread.currentThread();
//2.查看当前线程
System.out.println("名称:"+th.getName());//名称
System.out.println("状态:"+th.getState());//状态
System.out.println("ID:"+th.getId());//ID
System.out.println("优先级:"+th.getPriority());//优先级
method();
//3.创建一个子线程,启动了一个线程,其实做了一个异步操作
ThreadDemo th1=new ThreadDemo();
//给线程命名
th1.setName("尊");
//启动线程 不能直接调用run方法,必须通过start来调用
th1.start();
System.out.println("执行完毕!");
}
}
输出结果:
2.2实现Runnable接口
/**
* ThreadDemo1实现Runnable这个接口
* ThreadDemo1不是线程类
* */
package day24.thread;
public class ThreadDemo1 implements Runnable{
@Override
public void run() {
// 线程体
System.out.println("线程名称:"+Thread.currentThread().getName());
}
public static void main(String[] args) {
//创建一个ThreadDemo1的实例
ThreadDemo1 demo=new ThreadDemo1();
//创建一个线程对象,执行demo对象
Thread th=new Thread(demo,"qq");
//启动线程
th.start();
//再次启动一个线程
Thread th1=new Thread(demo,"ww");
th1.start();
}
}
3.线程的方法
3.1基本方法
3.1.1线程优先级
package day25.thread;
public class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 120; i++) {
System.out.println(Thread.currentThread().getName()+"\t优先级:"+Thread.currentThread().getPriority());
}
}
public static void main(String[] args) {
//初始三个线程
ThreadDemo demo=new ThreadDemo();
ThreadDemo demo1=new ThreadDemo();
ThreadDemo demo2=new ThreadDemo();
//命名
demo.setName("A");
demo1.setName("B");
demo2.setName("C");
//设置优先级1-5 默认是5
demo.setPriority(MIN_PRIORITY);
demo1.setPriority(MAX_PRIORITY);
//启动
demo.start();
demo1.start();
demo2.start();
}
}
输出结果:
3.1.2线程状态
package day25.thread;
public class ThreadDemo2 extends Thread{
@Override
public void run() {
System.out.println("运行状态:"+Thread.currentThread().getState()+"\t激活:"+Thread.currentThread().isAlive());
}
@SuppressWarnings("static-access")
public static void main(String[] args) throws InterruptedException {
//初始化对象
ThreadDemo2 demo2=new ThreadDemo2();
System.out.println("创建状态:"+demo2.getState()+"\t\t激活:"+demo2.isAlive());
//启动线程
demo2.start();
System.out.println("启动状态:"+demo2.getState()+"\t激活:"+demo2.isAlive());
demo2.sleep(2000);
System.out.println("完毕状态:"+demo2.getState()+"\t激活:"+demo2.isAlive());
}
}
输出结果:
3.1.3线程同步
package day25.thread;
public class ThreadDemo1 extends Thread{
@Override
public void run() {
try {
System.out.println("生日快乐");
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("七夕快乐!");
}
public static void main(String[] args) throws InterruptedException {
// 初始化对象
ThreadDemo1 demo1=new ThreadDemo1();
//启动线程
demo1.start();
//合并线程,demo1和主线程合并
//demo1.join();//join在start之后使用
//主线程执行方法
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
if (i==3) {
demo1.join();
}
System.out.println("i====="+i);
}
}
}
输出结果:
3.1.4线程礼让
package day25.thread;
public class ThreadDemo3 implements Runnable{
@SuppressWarnings("static-access")
@Override
public void run() {
for (int i = 0; i < 6; i++) {
if (i==3) {
//礼让线程
Thread.currentThread().yield();
System.out.println("礼让");
}
System.out.println("i=="+i+" "+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
// 初始化对象
ThreadDemo3 demo3=new ThreadDemo3();
//创建线程
Thread th1=new Thread(demo3,"qq");
Thread th2=new Thread(demo3,"rr");
Thread th3=new Thread(demo3,"uu");
//启动线程
th1.start();
th2.start();
th3.start();
}
}
输出结果:
3.1.5线程守护
package day25.thread;
public class ThreadDaemonDemo extends Thread{
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("七夕节快乐");
}
}
public static void main(String[] args) throws InterruptedException {
//创建对象
ThreadDaemonDemo demo=new ThreadDaemonDemo();
//把当前线程设为守护线程,需要在启动之前设置
demo.setDaemon(true);
//启动线程
demo.start();
System.out.println("不快乐!");
Thread.sleep(3000);
System.out.println("喝酒");
}
}
输出结果:
3.2锁
3.2.1synchronized修饰符
/**
* synchronized修饰符
* 可以修饰方法,锁住的是当前对象this
* 可以修饰代码块
* 同步的意思
* */
package day25.thread;
public class AppleDemo implements Runnable {
//苹果数量
private int count=50;
private static Object obj=new Object();
//修饰方法修饰的是this对象
public synchronized void method(){
if (count>0) {
System.out.println(Thread.currentThread().getName()+"1吃了第"+count+"个苹果");
count--;
}
}
public void method1() {
synchronized (obj) {//同步代码块,作用域精确
if (count>0) {
System.out.println(Thread.currentThread().getName()+"2吃了第"+count+"个苹果");
count--;
}
}
}
@Override
public void run() {
// 吃苹果
for (int i = 0; i < 50; i++) {
//method();
method1();
}
}
public static void main(String[] args) {
// 初始化对象
AppleDemo demo=new AppleDemo();
//创建线程,启动线程
Thread th1=new Thread(demo,"A");
th1.start();
Thread th2=new Thread(demo,"B");
th2.start();
Thread th3=new Thread(demo,"C");
th3.start();
}
}
输出结果:
3.2.2互斥锁ReentrantLock
package day25.thread;
import java.util.concurrent.locks.ReentrantLock;
public class AppleLock implements Runnable {
private int count=50;
//创建一个互斥锁
ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
for (int i = 0; i < 50; i++) {
//上锁
lock.lock();
try {
if (count>0) {
System.out.println(Thread.currentThread().getName()+"吃了第"+count+"个苹果");
count--;
}
} catch (Exception e) {
// TODO: handle exception
}finally {
//释放锁
lock.unlock();
}
}
}
public static void main(String[] args) {
// 初始化对象
AppleLock app=new AppleLock();
//启动三个线程
new Thread(app, "A").start();
new Thread(app, "B").start();
new Thread(app, "C").start();
}
}
输出结果:
3.2.3死锁
package day25.thread;
//死锁
public class DeadLockDemo implements Runnable{
//全局变量
boolean isFlag=false;
Object obj=new Object();
Object obj1=new Object();
//一个线程执行A
public void methodA() {
System.out.println("methodA=="+Thread.currentThread().getName());
synchronized (obj) {
System.out.println("obj已经加锁");
synchronized (obj1) {
System.out.println("访问obj1");
}
System.out.println("obj1访问结束");
}
System.out.println("obj已经解锁");
}
//一个线程执行B
public void methodB() {
System.out.println("methodB=="+Thread.currentThread().getName());
synchronized (obj1) {
System.out.println("----->obj1已经加锁");
synchronized (obj) {
System.out.println("------>访问obj");
}
System.out.println("------>obj访问结束");
}
System.out.println("------>obj1解锁");
}
@Override
public void run() {
if (!isFlag) {
isFlag=!isFlag;
methodA();
}else {
methodB();
}
}
public static void main(String[] args) {
// 创建对象
DeadLockDemo demo=new DeadLockDemo();
//启动两个线程
new Thread(demo, "A").start();
new Thread(demo, "B").start();
}
}
输出结果:
3.3定时器Timer
package day25.timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class Task extends TimerTask{
@Override
public void run() {
// 计时器要执行的任务
System.out.println("上九天揽月,下五洋捉鳖!");
}
}
public class TimerDemo {
public static void main(String[] args) throws ParseException {
// 创建一个计时器对象,可以设置为守护线程+true
Timer timer=new Timer();
//添加执行的任务
//获取当前时间戳
Calendar c=Calendar.getInstance();
Long times=c.getTimeInMillis();
//3s后执行
times+=3*1000;
//设置时间
c.setTimeInMillis(times);
//获取日期
Date date=c.getTime();
//指定时间
SimpleDateFormat frm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//将String类型的时间解析为Date
date=frm.parse("2018-08-17 16:39:40");
Task ts=new Task();
timer.schedule(new Task(), date);//在指定的时间来执行指定的任务
timer.schedule(new TimerTask() {
@Override
public void run() {
// 执行任务
System.out.println("送你一颗小星星");
}
}, 5000);//以当前时间延迟多少毫秒执行一次任务
//指定首次出现时间
date=frm.parse("2018-08-17 16:45:00");
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("我不要!");
}
}, date, 10000);//在指定的时间执行任务,以一定的延时重复执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("那就分手吧!");
}
}, 2000, 5000);//以当前时间延迟多少s,再以固定的时间重复执行
//取消指定任务
//ts.cancel();
//取消timer内所有任务
//ts.cancel();
//清空已结束任务
//System.out.println(timer.purge());
}
}
输出结果:
3.4单例设计模式
/**
* 单例设计模式
* 当前该类只能有一个对象,这个对象是共享的
* */
3.4.1懒汉模式
package day25.singleton;
//懒汉模式
public class SingletonDemo {
String name;
private static SingletonDemo singleton=null;
//构造方法私有化
private SingletonDemo(){
}
//通过类来获取对象,设计一个静态的方法
public static synchronized SingletonDemo getIntance() {
//创建对象,返回对象
if (singleton==null) {
singleton=new SingletonDemo();//初始化一个对象
}
return singleton;//将对象返回到方法调用处
}
}
package day25.singleton;
public class TestDemo {
public static void main(String[] args) {
/*SingletonDemo demo=SingletonDemo.getIntance();
demo.name="zz";
System.out.println(demo);
SingletonDemo demo1=SingletonDemo.getIntance();
System.out.println(demo1);
System.out.println(demo1.name);*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
}
}
输出结果:
3.4.2饿汉模式
package day25.singleton;
//饿汉模式
public class SingletonDemo1 {
private static final SingletonDemo1 singleton=new SingletonDemo1();
//构造方法私有化
private SingletonDemo1(){
}
//通过类来获取对象,设计一个静态的方法
public static synchronized SingletonDemo1 getIntance() {
return singleton;
}
}
package day25.singleton;
public class TestDemo1 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
}
}
输出结果:
3.5生产者消费者模型
package day25.test;
/**
* 生产者与消费者模型中,要保证以下几点:
* 1 同一时间内只能有一个生产者生产 生产方法加锁sychronized
* 2 同一时间内只能有一个消费者消费 消费方法加锁sychronized
* 3 共享空间空时消费者不能继续消费 消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行
* 4 共享空间满时生产者不能继续生产 生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行
*/
/**
* 生产者: 一直生产,直到生产完10个
* 在生产过程中,如果库存中存满(1个)则停止生产(由resource控制)
*/
//生产者
class Producer implements Runnable{
private ShareResource resource;//共享资源对象
public Producer(ShareResource resource) {
this.resource=resource;
}
@Override
public void run() {
System.out.println("生产中。。。");
for (int prodect = 1; prodect <=100; prodect++) {
try {
resource.setProdect(prodect);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
/**
* 消费者:不断消费,直到消费10个
* 消费过程中,如果库存有包子则消费,没包子等待(resource中wait())
*/
//消费者
class Consumer implements Runnable{
private ShareResource resource;//共享资源对象
public Consumer(ShareResource resource) {
this.resource=resource;
}
@Override
public void run() {
System.out.println("消费中。。。");
for (int i = 1; i <= 100; i++) {
try {
resource.getProdect();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
/**
* 共享资源: 负责控制库存,如果库存没包子了:通知生产者开始生产(notify), 并且通知消费者等待(wait)
* ,如果库存有包子:通知生产者停止生产(wait), 并且通知消费者开始消费(notify)
* notify() / notifyall() :通知 实质上相当于 唤醒
* 加synchronized 为了保证,同一时刻只有一个生产者在生产,只有一个消费者在消费
*/
//共享资源
class ShareResource{
private int prodect=-1;
public synchronized void setProdect(int prodect) throws InterruptedException {
waitIfFull();//如果满,等待 被唤醒后继续执行
this.prodect=prodect;
System.out.println("生产包子"+prodect+"个");
notify();
}
public synchronized int getProdect() throws InterruptedException {
waitIfEmpty();//如果空,等待 被唤醒后继续执行
int p=this.prodect;
System.out.println("消费者购买了"+p+"个包子");
this.prodect=-1;
notify();
return p;
}
private synchronized void waitIfEmpty() throws InterruptedException {
if (prodect==-1) {
System.out.println("消费者等待!");
wait();
}
}
private synchronized void waitIfFull() throws InterruptedException {
if (prodect!=-1) {
System.out.println("生产者等待!");
wait();
}
}
}
public class ProducterComsumerDemo {
public static void main(String[] args) {
//初始化对象
ShareResource resource=new ShareResource();
//启动线程
new Thread(new Producer(resource)).start();
new Thread(new Consumer(resource)).start();
}
}
输出结果:
4.知识框架