前言
小编最近在学习线程的内容,发现里面的小例子实现起来非常的有意思,当然也非常有用,线程的内容,几乎是我们每天都会遇到,但是不是特别注意的,下面小编带大家进一步认识线程吧!
线程和进程
1.线程是一个程序内部的顺序控制流2.线程和进程区别:
(1)每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销;
(2)线程可以看成轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小;
(3)多进程:在操作系统中能同时运行多个任务(程序);
(4)多线程:在同一个应用程序中有多个顺序流同时执行。
线程同步
在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。
1.对象互斥锁
每个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任何一时刻,只能有一个线程访问该对象。
2.关键字synchronized
synchronized来与对象的互斥锁联系,当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
生产者和消费者的例子
1.代码分析
(1)共有5个类:主程序类ProducerConsumer、生产的食物类WoTou、实现线程同步的加锁类SyncStack、生产者类Producer和消费者类Consumer
(2)Producer和Consumer实现了接口Runnable,属于两个线程;
(3)当在执行线程同步时,如果生产的数量超出了容器即数组的索引值6的话,则执行Object.wait()的方法,否则激活另一个线程消费Consumer,使用Object .notify()方法。
2.代码实现
public class ProducerConsumer {
public static void main(String[] args) throws Exception{
SyncStack ss=new SyncStack();
Producer p=new Producer(ss);
Consumer c=new Consumer(ss);
new Thread(p).start();
new Thread(c).start();
}
}
class WoTou{
int id;
WoTou(int id){
this.id=id;
}
public String toString(){
return "wotou: "+id;
}
}
class SyncStack{
int index=0;
WoTou[] arrWT=new WoTou[6];
public synchronized void push(WoTou wt){
while(index==arrWT.length){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notify();
arrWT[index]=wt;
index++;
}
public synchronized WoTou pop(){
while(index==0){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notify();
index--;
return arrWT[index];
}
}
class Producer implements Runnable{
SyncStack ss=new SyncStack();
Producer(SyncStack ss){
this.ss=ss;
}
public void run(){
for(int i=0;i<=20;i++){
WoTou wt=new WoTou(i);
ss.push(wt);
System.out.println("生产了 "+wt);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
SyncStack ss=new SyncStack();
Consumer(SyncStack ss){
this.ss=ss;
}
public void run(){
for(int i=0;i<=20;i++){
WoTou wt=ss.pop();
System.out.println("消费了 "+wt);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
小结
线程同步,是在面试中经常可以会被问到的题目,这个小例子如果自己能够动手写出来,充分理解之后,相信会很有帮助。