哪个网站做非洲的生意,如何建立网站是什么,创作服务平台,适合个人公众号的名字线程 概念
1.程序:未解决某种问题,使用计算机语言编写的一些列指令(代码)的集合
2.进程:正在运行的程序(被加载到内存中),是操作系统进行资源分配的最小单位
3.线程:进程可以进一步细化为线程(比进程更小)且线程是隶属于进程的,是操作系统执行的最小的执行单元 也是cpu进行任…线程 概念
1.程序:未解决某种问题,使用计算机语言编写的一些列指令(代码)的集合
2.进程:正在运行的程序(被加载到内存中),是操作系统进行资源分配的最小单位
3.线程:进程可以进一步细化为线程(比进程更小)且线程是隶属于进程的,是操作系统执行的最小的执行单元 也是cpu进行任务调度的最小单位
如 :运行的QQ也是一个进程,操作系统就会为这个进程分配资源 一个聊天窗口就是一个线程,线程隶属于进程
tips:早期是没有线程的,是以进程为单位执行的,进程的单位比较大,当一个进程运行时,其他进程就不能执行了,所以后来,将进程中的多个任务细化为线程,cpu的执行单位,也是从进程进化为更小的线程
总结
一个进程可以包含多个线程一个线程只能隶属于一个进程,线程不能脱离进程单独独立运行一个进程中至少有一个线程,即主线程,java中mian方法就是用来启动主线程在主线程中可以创建并启动其他线程,所有线程都共享进程的内存资源所有线程都共享进程资源
Thread类
在Java中Thread表示线程,提供了许多的方法,来对线程的控制,可以通过继承Thread 类来实现线程
Thread常用方法
Thread.currentThread(); 获取当前运行的线程 run(); 线程要执行的任务 start(); 启动Java线程 setName(String name); 设置线程名字 (String)getName(); 获取线程名字 getPriority(); 获取线程优先级 setPriority(); 设置线程优先级 1~10一般线程默认优先 5 sleep(long ms); 设置线程休眠 join(); 让其他线程等待这个线程结束后,其他线程再执行
Thread构造方法
new Thread(Runnable runnable); 接受一个任务对象 new Thread(Runnable runnable,String name); 接受一个对象 并为对象设置名字
使用上面方法进行实例
线程1
public class MyThread extends Thread{//重写run方法,在run中执行我们要执行的方法Overridepublic void run() {for(int i0;i10000;i){System.out.println(循环maini);}}}线程2
public class MyThread2 extends Thread {Overridepublic void run() {for(int i0;i10000;i){System.out.println(循环main2i);}}
}public class 线程 {public static void main(String[] args) {for(int i0;i10000;i){System.out.println(循环1 i);}for(int i0;i10000;i){System.out.println(循环2 i);}for(int i0;i10000;i){System.out.println(循环3 i);}for(int i0;i10000;i){System.out.println(循环4 i);}/*这样不管怎么执行都是单线程,从上到下依次执行,所以如果想在java程序中有几件不想管的事件同时执行可以在java中创建线程,把一些需要执行的任务放在线程中执行,这样就拥有让cup执行的权利*/MyThread myThread new MyThread();//调用start方法让程序多线程进行,重写run方法但不能调用run,不然只是普通方法的调用,依然是单线程myThread.start();MyThread2 myThread2 new MyThread2();myThread2.start();}}观察结果 可知 MyThread与MyThread2是同时进行的
Runnable接口
Java中我们也可以实现Runnable接口来进行对线程的实现
思路. 创建一个类 实现Runnable接口 重写run方法 在main函数使用Thread构造方法传入Runnable对象 public class MyTask implements Runnable{Overridepublic void run() {for(int i0;i10;i){System.out.println(啊);}}
}MyTask myTask new MyTask();//创建一个线程Thread thread new Thread(myTask);Callable接口
Java中也可以实现Callable接口 重写 call()方法 来对线程的实现
思路.
重写call()方法 call()方法有返回值 可以抛出异常,还可以处理不同类型依然使用Thread构造方法来创建一个线程
关于线程的其他概念
线程生命周期
从线程到销毁期间经历五个状态 守护线程(也是线程的一种)
setDaemon();如果一个**线程是守护线程**,那么它会等待java中其他线程任务结束后,自动终止守护线程是为其他线程提供服务的,eg:jvm中的垃圾回收机制,就是一个守护线程
多线程
在一个应用程序中,存在多个线程,不同线程可以并行的执行任务
*操作系统线程任务调度算法
先来先服务调度算法短作业优先调度算法优先级调度算法高响应比优先调度算法时间片轮转调度算法多级反馈队列调度算法(集合前几种算法的优点)
对线程进行加锁
分析
多线程的优点 提高程序的处理能力提高CPU的 利用率 缺点 线程也是需要占用内存资源和CPU资源多个线程对同一个共享资源进行访问,会出现线程安全问题
对于内存资源与CPU资源我们可以通过不断增加内存来解决
对于线程安全问题 我们则需要对 线程进行加锁
synchronized
synchronized 修饰代码块需要加一个同步对象 synchronized(同步对象)
同步对象要求
多线程用到的对象必须是同一个对象可以是java类中任何类对象.作用:用来记录有没有线程进入到同步代码块中
修饰方法
锁不需要我们提供,会默认提供锁对象synchronized如果修饰的是非静态方法,锁的对象是this如果是静态方法,锁的对象是Class的对象 (一个类只能有一个对象)
修饰代码块例子
package day17;public class PrintNums implements Runnable{//实现线程的交替打印int num100;Object object new Object();Overridepublic void run() {while(true){synchronized (object){object.notify();//唤醒线程if(num0){break;}System.out.println(Thread.currentThread().getName().num.);num--;try {object.wait();//线程等待} catch (InterruptedException e) {e.printStackTrace();}}}}
}
package day17;public class TestPrintNums {public static void main(String[] args) {PrintNums printNums new PrintNums();Thread t1 new Thread(printNums,1);Thread t2 new Thread(printNums,2);Thread t3 new Thread(printNums,3);t1.start();t2.start();t3.start();}
}于是我们实现了交替打印 每次只能进入一个线程
修饰方法(同步对象会有默认的)
锁不需要我们提供,会默认提供对象锁synchronized如果修饰的是非静态方法,锁的对象是this
synchronized如果修饰的是静态方法,锁的对象是类的Class对象,一个类只有 一个对象 如果是非静态方法,那么同步对象是this(如果是非静态对象,我们可以使用Runnable创建线程方法) 如果是静态方法,所得对象是当前类的Class对象 当前类的Class对象:一个类加载到内存后会为这个类创建唯一的Class类的对象 Class类实例表示正在运行的Java应用程序中的类和接口 修饰静态方法
public class SellTicket extends Thread {static int counts 10;//10张票static Object object new Object();Overridepublic void run() {while (counts 0) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}sellTicket();}}public static synchronized void sellTicket() {if(counts0){System.out.println(Thread.currentThread().getName()买了counts张票);--counts;}}
}
public class Test {public static void main(String[] args) {SellTicket t1 new SellTicket();t1.setName(窗口1);SellTicket t2 new SellTicket();t2.setName(窗口2);t1.start();t2.start();}
}修饰非静态方法
public class SellTickets2 implements Runnable{int t20;//票数Overridepublic void run() {while(t0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}sell2();}}public synchronized void sell2(){if(t0){System.out.println(Thread.currentThread().getName()买了t张票);--t;}}
}public class Test2 {public static void main(String[] args) {SellTickets2 sellTickets2 new SellTickets2();Thread t1 new Thread(sellTickets2,窗口1);Thread t2 new Thread(sellTickets2,窗口2);t1.start();t2.start();}
}ReentrantLock类加锁
只能对某一代码块进行加锁,不能对整个方法加锁加锁方法如下
ReentrantLock r new ReentrantLock();//创建 ReentrantLock对象
r.lock();---------|//加锁|............. |------被锁部分(一次只进去一个线程)|
r.unlock();-------|//解锁tips:r.unlock();最好写在finally{};代码块中,保证发生异常时,也能够解锁;
synchronized与ReentrantLock的区别 synchronized是一个关键字,ReentrantLock是一个类 synchronized修饰代码块和方法,ReentrantLock只能修饰代码块 synchronized可以隐式的加锁和释放锁,运行出现异常可以自动释放锁 ReentrantLock需要手动加锁和释放锁,建议在finally代码中释放锁
常用的三个方法 wait notify notifyAll wait();方法使当前线程进入等待状态直到另一个线程调用该对象的notify()或notifyAll()方法来唤醒它 notify();方法唤醒在该对象上调用wait()方法进入等待状态的一个线程如果有多个线程在等待则只会唤醒其中一个线程。 notifyAll();方法唤醒在该对象上调用wait()方法进入等待状态的所有线程。 tips:1.都是Object类中定义的方法 2.三个方法必须在同步代码块中使用 3.这三个方法必须通过为锁的对象调用