- 在网上查找了很多关于java多线程的知识,各位大牛对java 多线程的讲解和到位,我在这里主要是对大牛技术贴做一些自己的总结。
线程和进程
- 我们在讨论多线程的问题时,必然离不开区分进程和线程的话题,那什么是线程和进程?
在网上找了一个比较权威的解释:
进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。
进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。
其实用文字解释还是挺不好懂的,可以参考看看编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程这篇文章是讲得比较清楚的,我在这里就不多做详述了。
多线程的几种形式
- 继承Thread类
public class myThread extends Thread {
@Override
public void run() {
super.run();
}
}
- 实现Runnable接口
public class myThread implements Runnable {
@Override
public void run() {
}
}
其实这两种方式没有本质的区别,最终都会实现Runnable接口。
例子
- basket.java
public class Basket {
private int index = 0;
private ManTou[] manTous = new ManTou[10];
public synchronized void push(ManTou manTou){
while (index == manTous.length){
try{
System.out.println("篮子满了");
this.wait();
}catch (Exception e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"生产"+manTou.toString());
this.notify();
manTous[index] = manTou;
index++;
}
public synchronized ManTou pop(){
while (index == 0){
try {
System.out.println("篮子空了");
this.wait();
}catch (Exception e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"吃了"+manTous.toString());
ManTou manTou = manTous[--index];
this.notify();
return manTou;
}
}
basket 里面主要是两个方法:push和pop,实现了对篮子的两个动作。
- ManTou.java
public class ManTou {
private int id;
public ManTou(int id){
this.id = id;
}
@Override
public String toString() {
return "ManTou{" +
"id=" + id +
'}';
}
}
ManTou.java 定义了馒头的特性
- Consumer.java
public class Consumer implements Runnable {
public Basket basket;
public Consumer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ManTou manTou = basket.pop();
try {
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
消费者这边实现了一个从篮子里面拿走馒头的动作
- Producer.java
public class Producer implements Runnable {
private Basket basket;
public Producer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ManTou manTou = new ManTou(i);
basket.push(manTou);
try {
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
同样Producer也实现了一个将馒头装载到篮子的过程。
- main.java
public class ProducerConsumer {
public static void main(String[] args){
Basket basket = new Basket();
new Thread(new Producer(basket)).start();
new Thread(new Consumer(basket)).start();
}
}
结果
Thread-0生产ManTou{id=0}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=1}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=2}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=3}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=4}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=5}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=6}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=7}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=8}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=9}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=10}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=11}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=12}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=13}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=14}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=15}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=16}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=17}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=18}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
Thread-0生产ManTou{id=19}
Thread-1吃了[LMutiplThread.ManTou;@ef0cda1
这是简单的学习了java 多线程的知识,初步了解了多线程的工作原理。
网友评论