线程

程序、进程、线程

程序:一段指令组成一个完成特定功能或者是一组特定功能的集合
进程:当一个程序执行之后,编程对应的一个进程
线程:线程是进程中的一个执行单元,进程之所以能够执行是由于线程的存在,一个进程可能包含多个线程

为什么需要多线程而不是多进程进行通信或者执行?
	多进程之间开发:
		当一个应用程序变为对应的进程之后,首先会想到CPU申请资源(内存资源、执行资源......)
		如果开启多个应用程序,并在程序之间进行交互,那么也就意味着多个内存资源需要相互调用,这样会出现大量的资源消耗和计算成本的增加
		
	多线程开发:
		当一个应用程序变为对应的进城之后,首先会向CPU申请资源(内存资源、执行资源......)
		当前进程中的多个线程共享进程所申请下来的资源信息
		
	java中采用的是多线程开发
	
三者之间的区别:
创建线程的方式:
	java提供了Thread类,该类指定的就是一个线程对象
	1:启动多线程之后,运行打印结果不重要,重要的是打印顺序错乱;
	2:start方法执行时,调用了run方法中的代码,但是如何调用的呢?
	3:启动多线程时,通过调用run方法会怎样?不会启动线程,只是方法的调用,打印不乱序;
	
如何保证线程启动:调用start方法
总结1:
	1:继承Thread
	2:重写run方法
	3:创建子类对象
	4:调用start方法,从而启动该线程
package com.mage.thread;

public class Test01 {
	//main方法中的线程称之为主线程
	public static void main(String[] args) {
		//创建子类对象
		Sun s = new Sun();
		s.start();
		
		//main方法执行输出
		for(int i = 0;i<10;i++) {
			System.out.println("线程main执行》》》》"+i);
		}
	}
}

class Sun extends Thread{
	public void run() {
		for(int i =0;i<10;i++) {
			System.out.println("线程Sun执行》》》》"+i);
		}
	}
}
如何保证线程启动:调用start方法
总结2:
	1:实现Runnable接口
	2:重写run方法
	3:创建实现类对象
	4:创建Thread对象,并将实现类对象作为参数传入;
	5:调用start方法,从而启动线程
package com.mage.thread;

public class Test02 {
	public static void main(String[] args) {
		//创建实现类对象
		MySun ms = new MySun();
		//创建一个线程对象
		Thread td = new Thread(ms);
		td.start();
		
		//main方法打印输出
		for(int i = 0;i<10;i++) {
			System.out.println("main线程执行》》》》"+i);
		}
		
	}
}

class MySun implements Runnable{
	public void run() {
		for(int i = 0;i<10;i++) {
			System.out.println("MySun线程执行》》》》"+i);
		}
	}
}

线程的常见方法

getName:获取当前线程名称
getId:获取当前线程ID
getPriority:获取当前线程的优先级
currentThread:获取当前线程
isAlive:获取当前线程是否存活

虽然线程有优先级,但不是意味着优先级别高的线程先执行;
在java中永远不要考虑通过优先级别去控制线程的执行顺序,一定程度上优先级别高的线程高概率先执行,但不是一定;

守护线程:主程序以及GC线程,那么GC线程就是主线程的守护线程
	主程序如果执行结束,那守护线程一定执行结束,但守护线程执行结束,主线程不一定执行结束;
package com.mage.thread;

public class Test03 {
	public static void main(String[] args) {
		//线程的常见方法
		//获取当前线程
		Thread currentThread = Thread.currentThread();//获取当前正在执行的线程
		System.out.println(currentThread.getId());
		
		//创建线程对象
		Demo dm = new Demo("A");
		dm.setDaemon(true);
		dm.start();
		
		//获取线程的优先级
		System.out.println(Thread.MAX_PRIORITY);
		System.out.println(Thread.NORM_PRIORITY);
		System.out.println(Thread.MIN_PRIORITY);
		
		//获取当前线程的优先级别
		System.out.println("主线程的优先级别:"+currentThread.getPriority());
		//设置线程的优先级别
		currentThread.setPriority(10);
		System.out.println("主线程的优先级别:"+currentThread.getPriority());
		
		//是否存活
		System.out.println(dm.isAlive());
		//是否是守护线程
		System.out.println(dm.isDaemon());
	}
}

class Demo extends Thread{
	public  Demo(String name){
		super(name);
	}
	
	public void run() {
		System.out.println(this.getName());
	}
}

interrupt 中断线程,并给当前线程增加一个中断标示位
isInterrupted 判定当前线程是否中断
interrupted 静态方法 ,判定当前线程是否中断 在判定结束之后会清楚中断标示位
package com.mage.thread;
/**
 * 		interrupt:中断线程,给当前线程增加一个中断标示位
 * 		isInterruped:判定当前线程是否中断
 * 		interrupted:静态方法,判定当前线程是否中断,在判定结束之后会清除中断标示位
 * 
 * 
 * */
public class Test02 {
	public static void main(String[] args) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i = 0;i<10;i++) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {			
						e.printStackTrace();
					}
					while(!Thread.interrupted()) {
						System.out.println("当前线程正在执行》》》》"+i);
					}
				}
			}
		});
		t.start();
		
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//中断线程,并给当前线程加一个中断标示
		t.interrupt();
		
	}
}

代理模式


线程的同步策略

同步器、锁机制
synchronized
用法:
	用来修饰方法:
		修饰非静态方法时,同一时间只能有一个线程访问该方法,该线程执行完整个方法之后会将锁释放,其它线程才能继续执行;
		
		修饰静态方法时,synchronized锁的对象其实是当前类的class对象
		
	同步代码块:
		synchronized(锁芯){
            
		}
		
	锁芯:对象,如果是非静态方法使用,首选this对象
		静态方法使用,首选类的class对象
		
package com.mage.thread.syc;

public class Test03 {
	public static void main(String[] args) {
		TicketRun1  t = new TicketRun1();
		for(int i =0;i<5;i++) {
			new Thread(t,"窗口"+i).start();
		}
	}

}

class TicketRun1 implements Runnable{
	int count = 10;
	
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			synchronized(this) {
				if(count>0) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"正在检票"+(count--));
				}
			}
		}
	}
}
package com.mage.thread.syc;

public class Test04 {

	public static void main(String[] args) {
		T t = new T();
		t.start();
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		t.flag = false;
	}

}

class T extends Thread{
	volatile boolean flag = true;
	@Override
	public void run() {
		System.out.println("while循环开始》》》");
		while(flag) {
			
		}
		System.out.println("while循环结束》》》");
	}
}
++ 不具备原子性,不可分割
例如:count++
	temp = count;
	(表达式)count = temp;
	(变量)count = count+1;
package com.mage.thread.syc;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 		++不具备原子性,不可分割
 * 				count++:
 * 					temp = count;
 * 					count = temp;
 * 					count = count + 1
 * 
 * */
public class Test05 {
	public static void main(String[] args) {
		for(int i =0;i<5;i++) {
			new Tt().start();
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("最后结果:"+Tt.count.get());
	}
}

class Tt extends Thread{
	static volatile AtomicInteger count = new AtomicInteger(0);
	
	@Override
		public void run() {
			for(int i = 0;i<1000;i++) {
				count.getAndIncrement();
			}
		}
}

生产者,消费者模式

package com.mage.thread.part;

import java.io.ObjectInputStream.GetField;
import java.util.concurrent.TimeUnit;

public class Good {
	private String type;
	private String name;
	// 代表有无商品
	private boolean flag = false;

	public Good() {
		// TODO Auto-generated constructor stub
	}

	public Good(String type,String name) {
		super();
		this.type = type;
		this.name = name;
	}
	 
	public String getType() {
		return type;
	}
	
	public void setType(String type) {
		this.type = type;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	//生产对象
	public synchronized void product(int i) {
		if(flag) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(i%2==0) {
			this.setType("可口可乐");
			try {
				TimeUnit.MILLISECONDS.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.setName("可乐");
		}else {
			this.setType("SkII");
			try {
				TimeUnit.MILLISECONDS.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.setName("神仙水");
		}
		System.out.println("开始生产:商品"+this);
		//改变flag的值
		flag = true;
		//叫醒等待的线程
		notifyAll();
	}
	
	//消费
	public synchronized void consumer() {
		if(!flag) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("开始消费:商品"+this);
		flag = false;
		notifyAll();
	}
	
	
	@Override
	public String toString() {
		return "[type="+type+"\tname="+name+"]";
	}
}

package com.mage.thread.part;

public class Product  extends Thread{
	private Good good;
	public Product(Good good) {
		this.good = good;
	}
	@Override
	public void run() {
		for(int i =1;i<10;i++) {
			good.product(i);
		}
	}

}

package com.mage.thread.part;

public class Consumer extends Thread{
	private Good good;
	
	public Consumer(Good good) {
		this.good = good;
	}
	@Override
	public void run() {
		for(int i=1;i<10;i++) {
			good.consumer();
		}
	}

}

package com.mage.thread.part;

public class GoodTest {
	public static void main(String[] args) {
		Good g = new Good();
		Product p = new Product(g);
		Consumer c = new Consumer(g);
		p.start();
		c.start();
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值