什么是线程,什么是进程
进程:是一个应用程序
线程:是一个进程的执行场景/执行单元
在java程序中,运行后会先启动JVM进程,而JVM会启用一个main方法和GC垃圾回收站这两个进程。
进程A与B内存不共享,线程A与线程B在Java语言中:堆内存与方法区内存共享,但栈内存是独立的,一个线程一个栈。
//方法一:继承Thread类
class MyThread1 extends Thread{
@Override
public void run(){
for (int i=0;i<=100;i++){
System.out.println("线程一,继承类Thread:"+i);
}
}
}
实例化(创建)线程:
Thread t1 = new MyThread1();
t1.start();
//实现Runable接口,并不是线程,只是一个可运行的对象
class MyThread2 implements Runnable{
@Override
public void run() {
for (int i=0;i<=10;i++){
System.out.println("线程二,实现接口Runnable:"+i);
}
}
}
实例化(创建)线程:
MyThread2 mt = new MyThread2();
Thread t2 = new Thread(mt);
t2.start();
//方法一 继承Thread类
new Thread(){
@Override
public void run(){
for(int i=0;i<100;i++){
System.out.println("方法一:"+i);
}
}
}.start();
//方法二:实现Runnable接口
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("方法二:" + i);
}
}
});
thread.start();
//创建一个”未来任务类“对象
FutureTask task = new FutureTask(new Callable(){
@Override
public Object call() throws Exception {
return null;
}
});
1,怎么获取线程对象 currentThread(); start Thread静态方法
出现在那就是那个线程
2,获取线程名字 getName();
3,修改线程名字 setName();
4,当线程没有设置名字是,默认名称:
Thread——0;
Thread——1;
Thread——2;
......
5,线程的sleep方法 sleep();
静态方法,参数是毫秒,作用是让当前线程进入休眠状态
Thread.sleep(); 方法间隔特定的事件去执行一段特定的代码,阻塞当前线程
注意:在哪那个线程休眠,与前面引用的对象无关
6.唤醒休眠线程 interrupter(); 靠的是java异常机制
7,强行终止一个线程 stop();(已过时) 直接终止一个线程,容易丢失数据
8,合理的终止 在run里面加一个if语句进行修改false与true
```java
public static void main(String[] args) {
//获取当前线程对象(出现在main方法中,就是main线程)
Thread currentThread =Thread.currentThread();
System.out.println(currentThread.getName());
//创建线程对象
Mythread02 t = new Mythread02();
//设置线程名字
t.setName("ttttt");
//线程休眠
try {
//一下三行代码的作用都是一样让主线main程休眠
t.sleep(5000);
currentThread.sleep(2000);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//获取线程名字
String s = t.getName();
System.out.println(s);
t.start();
t.interrupt();
}
class Mythread02 extends Thread{
@Override
public void run(){
for (int i=0;i<=100;i++){
try {
//特定时间执行
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程一,继承类Thread:"+i);
}
}
}
/* 线程调度:
1,实例方法:
void setPriority(int newPriority) 更改此线程的优先级。
int getPriority() 返回此线程的优先级。
最低为1,最高为10
优先级高获得的时间片可能更多
2,静态方法 yield() 让位方法,暂停当前执行的线程状态,不是阻塞方法
3,实例方法 join() 合并线程
*/
System.out.println("最高优先级"+Thread.MAX_PRIORITY);
System.out.println("最低优先级"+Thread.MIN_PRIORITY);
System.out.println("默认优先级"+Thread.NORM_PRIORITY);
//获取当前线程优先级
Thread currentThread = Thread.currentThread();
System.out.println(currentThread.getPriority());
//设置主线程优先级
Thread.currentThread().setPriority(1);
Thread t = new Mythread03();
t.setPriority(10);
t.start();
for(int i =0;i<1000;i++){
System.out.println("---->"+i);
}
1.守护线程
java语言线程分为两类:用户线程和守护线程(后台线程)
守护线程的特点:一般守护线程是一个死循环, 所有用户线程结束守护线程就结束。比如:垃圾回收线程GC
public class ThreadSHXC {
public static void main(String[] args) {
Thread t = new BakDateThread();
t.setName("数据备份");
t.setDaemon(true);
t.start();
//主线程
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"--->"+(++i));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//数据备份
class BakDateThread extends Thread{
public void run(){
int i =0;
while(true){//即使是死循环,也会自动退出
System.out.println(Thread.currentThread().getName()+"--->"+(++i));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2,定时器
定时器的作用:
间隔特定的时间,并执行特定的程序。
在java,util.Timer,可以直接拿来用。(不过后期许多框架都支持定时任务)
//创建定时器对象
Timer time = new Timer();
//指定定时任务
//time.schedule(定时任务,执行时间,间隔多久);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date fristTime = sdf.parse("2020-09-27 18:10:00");
time.schedule(new LogTimeTask(),fristTime,1000*3);
//匿名内部类方式
time.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("匿名内部类");
}
},fristTime,1000*3);
}
3,关于object类中的wait和notify方法(生产和消费者模式)
wait和notify方法不是线程对象特有的方法,是java中任何一个java对象都有的方法,Object类自带的
wait:
Object o = new Object();
o.wait();
表示:让正在o对象上的线程进入等待状态,无期限等待,直到被唤醒
notify:
Object o = new Object();
o.notify();唤醒等待
生产者和消费者模式:
/*
生产者和消费者模式:使用wait与notify方法
1,什么是生产者和消费者模式?
生产线程负责生产,消费线程负责消费,两者达到平衡
2,两个方法建立在线程同步的基础之上
3,o.wait方法的作用:让线程进入等待状态,释放对象锁
4,o.notify()让正在等待的对象唤醒,只是通知,不会释放o对象之前的锁
模拟这样一个需求
仓库采用LIst集合。
保证仓库永远只有一个元素,达到生产一个消费一个
*/
public class ThreadSHX {
public static void main(String[] args) {
List list = new ArrayList() ;
//创建两个线程对象
//生产者
Producer producer = new Producer(list);
Thread t1= new Thread(producer);
//消费者
Consumer consumer = new Consumer(list);
Thread t2= new Thread(consumer);
t1.setName("生产者线程");
t2.setName("消费者线程");
t1.start();
t2.start();
}
}
//生产线程
class Producer implements Runnable{
private List list; //仓库
public Producer(List list) {
this.list=list;
}
@Override
public void run() {
//一直生产
while(true){
synchronized (list) {
if (list.size() > 0)
//当前线程进入等待状态
{
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "---->" + obj);
list.notify();
}
}
}
}
//消费线程
class Consumer implements Runnable{
private List list; //仓库
public Consumer(List list) {
this.list=list;
}
@Override
public void run() {
//一直消费
while(true){
synchronized (list){
if(list.size()==0){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName()+"---->" + obj);
list.notifyAll();
}
}
}
}