进程
一个程序的运行状态和资源占用的描述
进城是程序的一个动态过程,指的是从代码加载到执行完毕的一个完成过程
特点:独立性,动态性,并发性
1)每个进程都有一个主线程
2)一个进程可以创建若干个线程
3)各个线程抢占进程的资源(CPU 内存)
4)进程之间不共享资源,相互独立
多线程
早期的操作系统都是单进程,如DOS操作系统,同一时间只能操作一件事情.
iOS也是单进程
多进程:在操作系统中能(同时)运行多个任务(程序)
(CPU飞速切换,看起来像在同时做的)
多线程:在同一应用程序中有多个顺序流(同时)执行
一个程序一个进程,下有多个线程

创建线程的方法:
1.定义一个线程类,继承类Thread并重写其中的方法run();.方法run()称为线程体.
public class ThreadT extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("ThreadT--->" + i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
ThreadT tf = new ThreadT();
tf.start();
for (int i = 0; i < 10; i++) {
System.out.println("main--->" + i);
}
}
}
2.提供一个实现接口Runnable的类作为县城的目标对象,在初始化一个Thread类或Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体。
public class ThreadT2 implements Runnable {
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("run--" + i);
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
ThreadT2 t2 = new ThreadT2();//生成一个Runnable接口实现类的对象
Thread tr = new Thread(t2);//生成一个Thead对象,并将Runnable接口实现类的对象作为参数传给该Thread对象
tr.start();//通知Thread对象执行start方法
for (int i = 0; i < 20; i++) {
System.out.println("main---" + i);
}
}
}
现成的简单控制方法
中断线程:
1)Thread.sleep(time);//当前线程休眠一段时间,休眠结束后就绪继续抢cpu,抢到了才执行
public class ThreadT2 implements Runnable {
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("run--" + i);
if(i==10){
try{
Thread.sleep(2000);
}catch(Exception e){
System.out.println(e);
}
}
}
}
}
2)Thread.yield();//当前线程让出cpu,再抢cpu(???)
设置线程的优先级
3)getPriority();得到线程优先级
4)setPriority();设置线程的优先级
public class ThreadTest2 {
public static void main(String[] args) {
ThreadT2 t2 = new ThreadT2();
Thread tr = new Thread(t2);
tr.setPriority(Thread.MAX_PRIORITY);//设置线程的优先级 MAX_PRIORITY,MIN_PRIORITY
tr.start();
System.out.println(tr.getPriority());//得到线程优先级
}
}
5)Thread.join();//合并线程
多线程数据安全
线程同步错误:多线程共用同一份数据时会发生.
public class MyThread implements Runnable{
int i = 100;
public void run(){
while(true){
//同步代码块
synchronized(this){//同步锁
//另一个线程即使抢占cpu也需要等待拿到同步锁的线程完成代码块内的内容并释放同步锁
//Thread.currentThread()返回一个当前正在执行这段代码的线程的引用
System.out.println(Thread.currentThread().getName() + i);
i--;
Thread.yield();
if(i<0){
break;
}
}
}
}
}
public class Test{
public static void main(String[] args) {
MyThread myThread = new MyThread();
//生成两个Thread对象,但是这两个对象共用同一个线程体
Thread t1 = new Thread(myThread);
Thread t2 = new Thread(myThread);
t1.setName("线程a");
t2.setName("线程b");
t1.start();
t2.start();
}
}
synchronized关键字
同步锁锁住的不是代码块,是指定的对象
一旦一个线程获得了一个对象的同步锁,那么这个对象上面的所有其他的同步的代码都无法被其他线程执行,同步锁被释放之后才能执行
同步代码块可以明确的指出锁定的对象.
同步方法:
public synchronized void fun(){
}
同步方法锁住的是this,即调用这个方法的对象.
public class Service implements Runnable{
public void fun1(){
synchronized(this){
try{
Thread.sleep(1000*3)
}catch(Exception e){
System.out.println(e);
}
System.out.println("fun1");
}
}
public void fun2(){
synchronized(this){
System.out.println("fun2");
}
}
}
public class MyThread1 implements Runnable{
private Service service;
public MyThread1(Service service){
this.service = service;
}
public void run(){
service.fun1();
}
}
public class MyThread2 implements Runnable{
private Service service;
public MyThread2(Service service){
this.service = service;
}
public void run(){
service.fun2();
}
}
public class Test{
public static void main(String[] args){
Service service = new Service();
Thread t1 = new Thread(new MyThread1(Service));
Thread t2 = new Thread(new MyThread2(Service));
t1.start();
t2.start();
}
}
线程之间的通信
典型案例:生产者 消费者模式
wait();//线程停止执行,释放锁,在锁外边处于等待状态.是Object的方法.必须放在同步代码块中使用.
sleep();//Thread类的方法,指定休眠时间结束后线程自动进入就绪状态.休眠期间锁依然有效.可以在代码的任何位置使用
notify();//向其他等待的线程发出可执行通知,同时放弃锁
notifyAll();//