`

JAVA多线程

    博客分类:
  • java
阅读更多

多线程一般情况下有两个要求,第一个是同步第二个是并发。线程的同步并不代表它可以并发执行。

关于多线程这里有几个概念需要搞清楚:

1.同步:在写代码之前,自己需要搞清楚原子操作是什么以及操作的是否是共享资源(操作的必须是同一个对象,所以称为对象的锁)。

a) 所谓原子操作就是我的这一段代码在执行的时候,其它人需要等待我执行完,他才可以执行这一段代码。使用同步代码块synchronized(this){...}可以实现代码的同步,如果整个方法都需要同步,那么在方法前添加synchronized关键字,这样就将整个方法定为了原子操作这和同步代码块是等价的

b) 只有三种情况会释放对象的锁:第一种情况:执行完同步代码块;第二种情况:在执行同步代码块的过程中,遇到异常导致线程终止,锁也会被释放;第三种情况:在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进入对象的等待池(在执行同步代码块的过程中执行Thread.sleep()和Thread.yield()方法,当前线程放弃CPU,但不会释放锁)。

 

2.并发:这也可以叫做线程之间的通信,线程之间进行通信需要用到Object类的三个方法:wait(),notify()或notifyAll()。

 

3.线程并发与同步中要有等待池和锁池的概念。一般情况下在同步方法的最开始调用notifyAll(),此时会唤醒等待池中等待的线程,Java虚拟机把对象的等待池中所有的线程都转到对象的锁池中。当其中的线程有机会获得该对象的锁时就会被执行。当需要释放对象的锁时,调用wait()方法,此时线程释放对象的锁,Java虚拟机把该线程放到该对象的等待池中,该线程等待其它线程将它唤醒。(等待池和锁池的内容来自孙卫琴的《Java面向对象编程》400页,13.9线程通信)

 

好,了解了等待池,锁池,原子操作,线程通信这些概念就可以开始写一个例子(其中代码注释了一些细节)。

 

//共享资源
public class Stack {
	private String[] list = new String[2000];
	private int point = -1;

	public void push(String goods) {
		this.notifyAll();
		while (list.length - 1 == point) {// 这里要使用while而不能使用if
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		point++;
		list[point] = goods;
	}

	public String pop() {
		this.notifyAll();
		while (point == -1) {
			try {
				// 没有线程调用notify时,该线程会一直等待。
				// wait方法必须放在一个循环中,因为在多线程环境中,共享对象的状态随时可能被改变,当一个在对象等待池中的线程被唤醒后,并不一定立即恢复运行,
				// 等到这个线程获得了锁及CPU才可以继续运行,有可能此时对象的状态已经发生了改变,所以要用while
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		String goods = list[point];
		list[point] = null;
		point--;

		return goods;
	}

	public synchronized int getPoint() {
		return point;
	}
}
//生产者
public class Producer extends Thread {
	private Stack stack;

	public Producer(Stack stack) {
		this.stack = stack;
	}

	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			synchronized (stack) {//这里要特别注意,这段代码就是原子操作(getPoint(),push()和打印内容这三步都是需要同步的内容)
				String goods = "goods" + (stack.getPoint() + 1);
				stack.push(goods);
				System.out.println("生产..." + goods);
			}
		}
	}
}
//消费者
public class Consumer extends Thread {
	private Stack stack;

	public Consumer(Stack stack) {
		this.stack = stack;
	}

	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			synchronized(stack){//这里要特别注意,这段代码就是原子操作
				String goods = stack.pop();
				System.out.println("消费..." + goods);
			}
		}
	}
}

 

 

//执行例子
public class SyncTest {
	public static void main(String[] args) {
		Stack stack = new Stack();
		new Producer(stack).start();
		new Producer(stack).start();
		new Producer(stack).start();
		
		new Consumer(stack).start();
		new Consumer(stack).start();
		new Consumer(stack).start();
		new Consumer(stack).start();
		//此时程序不会执行完,因为消费者在等待生产者制造产品。
	}
}




 

 

分享到:
评论

相关推荐

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程编程技术

    《Java多线程编程核心技术》建议猿友们读两遍,因为其写得没有那么抽象,第一遍有些概念不是很理解,可以先跳过并记录起来,第一遍阅读的目的主要是了解整个架构。第二遍再慢慢品味,并贯穿全部是指点来思考,并将...

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程并发

    java多线程并发的在新窗口

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

    java多线程模拟队列实现排队叫号

    java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号

Global site tag (gtag.js) - Google Analytics