`
liulanghan110
  • 浏览: 1075522 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

JAVA并发控制的几种办法

    博客分类:
  • JAVA
阅读更多

假如有十张票,现在需要三个窗口(线程)卖,代码如下:

 

 

package com.test.runnable;

class MyThread implements Runnable {
	private int ticket = 10;
	public void run() {
		while (ticket > 0) {
			System.out.println("ticket = " + ticket--);
			try {
				Thread.sleep(2000l);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

 输出结果为:

 

ticket = 10

ticket = 9

ticket = 8

ticket = 7

ticket = 7

ticket = 7

ticket = 6

ticket = 5

ticket = 6

ticket = 4

ticket = 4

ticket = 3

ticket = 2

ticket = 1

ticket = 2

可以发现不止卖 了十张,所以要进行并发控制。

 

第一种办法,采用同步关键字

 

package com.test.runnable;

class MyThread implements Runnable {
	private int ticket = 10;
	synchronized public void run() {
		while (ticket > 0) {
			System.out.println("ticket = " + ticket--);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

 可以发现输出结果为:

 

ticket = 10

ticket = 9

ticket = 8

ticket = 7

ticket = 6

ticket = 5

ticket = 4

ticket = 3

ticket = 2

ticket = 1

这样多个窗口卖票,就能正确了,

 

2.也可以采用原子变量

 

package com.test.runnable;

import java.util.concurrent.atomic.AtomicInteger;

class MyThread implements Runnable {
	private AtomicInteger ticket = new AtomicInteger(10);
	synchronized public void run() {
		while (ticket.get() > 0) {
			System.out.println("ticket = " + ticket.getAndAdd(-1));
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

3.采用信号量Semaphore

package com.test.runnable;

import java.util.concurrent.Semaphore;

class MyThread implements Runnable {
	final Semaphore semp = new Semaphore(1);
	private  int ticket = 10;
	public void run() {
		// 获取许可
        try {
			semp.acquire();
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		while (ticket > 0) {
			System.out.println("ticket = " + ticket--);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 访问完后,释放
        semp.release();
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

 

 4.采用Lock

package com.test.runnable;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class MyThread implements Runnable {
	private Lock myLock = new ReentrantLock(); // 执行操作所需的锁对象
	private  int ticket = 10;
	public void run() {
		myLock.lock();
		while (ticket > 0) {
			System.out.println("ticket = " + ticket--);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 访问完后,释放
		myLock.unlock();
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

 

5.但不能采用volatile关键字,因为线程内变量的值更新依赖原值。

package com.test.runnable;

class MyThread implements Runnable {
	//private volatile int ticket = 10;
	private volatile int ticket = 10;
	public void run() {
		while (ticket > 0) {
			System.out.println("ticket = " + ticket--);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class RunnableDemo{
	public static void main(String[] args){
		MyThread my = new MyThread();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

 

 

分享到:
评论

相关推荐

    java并发编程实战源码,java并发编程实战pdf,Java

    在Java并发编程中,主要涉及以下几个关键知识点: 1. **线程与进程**:线程是程序执行的最小单元,一个进程中可以有多个线程同时执行。理解线程的概念和生命周期对于并发编程至关重要。 2. **线程安全**:当多个...

    java高并发写入用户信息到数据库的几种方法

    Java 高并发写入用户信息到数据库的几种方法 在 Java 高并发环境下,写入用户信息到数据库可能会出现一些问题,例如多个用户同时写入导致数据不一致或重复写入。为了解决这些问题,需要使用一些特殊的方法来确保...

    java并发编程2

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...

    java并发编程与实践

    2. **同步机制**:详述了Java中同步的几种方法,如`synchronized`关键字、volatile变量、Lock接口(如ReentrantLock)以及Condition。这些机制用于防止数据竞争和确保线程安全。 3. **并发工具类**:Java并发包...

    Java系统的高并发解决方法详解

    Java系统的高并发解决方法详解 ...Java系统的高并发解决方法可以通过静态化、图片服务器分离、数据库集群和库表散列、缓存等多种方法来实现,选择哪种方法需要根据实际情况进行选择和组合,以提高系统的性能和扩展性。

    Java并发编程学习笔记

    Java并发编程中还需要注意几个重要概念: - 原子性(Atomicity):是指一组操作,要么全部执行成功,要么全部不执行,不能存在执行了部分操作的情况。 - 竞争条件(Race Condition):多个线程对同一数据进行操作时...

    Java并发编程实践.pdf

    为了解决线程安全问题,Java提供了以下几种机制: - **synchronized关键字**:用于修饰方法或代码块,确保同一时刻只有一个线程可以执行被synchronized修饰的代码。 - **volatile关键字**:用于修饰变量,确保变量的...

    java并发程序设计

    本文将从以下几个方面详细讲解Java并发程序设计的核心知识点: 1. 使用线程的经验:线程是并发程序的基础,包括设置线程名称、响应中断信号以及使用ThreadLocal变量。设置线程名称有助于在多线程调试时容易识别线程...

    实战Java高并发程序设计(高清版)

    5. **J.U.C框架**:Java并发 utilities (J.U.C) 框架是Java并发编程的重要组成部分,书中会介绍如何利用这个框架来提升并发性能和代码的可读性。 6. **性能调优**:在高并发场景下,性能优化是必不可少的。可能涵盖...

    java并发编程经典书籍(英文版)

    Java并发编程是Java开发者必须掌握的关键技能之一,尤其是在多核处理器和分布式系统广泛使用的今天。以下是对标题和描述中提及的两本经典书籍——《Concurrent Programming in Java》和《Java Concurrency in ...

    [Java并发编程实践].(Java.Concurrency.in.Practice).Brian.Goetz.文字版(1)

    5. **并发设计模式**:书中详细阐述了几种常见的并发设计模式,如生产者-消费者模型、读写锁策略、工作窃取算法等,这些都是解决并发问题的有效手段。 6. **线程池**:Executor框架是Java并发编程的重要组成部分,...

    JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程

    可以通过以下几种方式来提升系统的并发能力: - **采用分布式架构**:将系统拆分为多个微服务,每个服务独立部署,根据负载情况进行水平扩展。 - **优化数据库性能**:使用读写分离、索引优化等手段提高数据库处理...

    java并发编程.docx

    Java提供了以下几种线程池实现: 1. FixedThreadPool:固定大小的线程池,如示例所示,核心线程数与最大线程数相同,使用LinkedBlockingQueue作为工作队列,可能导致内存溢出(OOM)如果任务请求过多。 2. ...

    java 多线程并发实例

    在并发控制中,我们通常会遇到以下几个关键概念: - 同步:确保同一时间只有一个线程访问共享资源,防止数据不一致。Java提供了synchronized关键字以及Lock接口(如ReentrantLock)来实现同步。 - volatile:修饰...

    ( java并发编程.zip )文字版 电子书 高清版

    Java并发编程的核心知识点包括以下几个方面: 1. **并发基础**:首先,我们需要了解并发的基本概念,如线程、进程、同步和互斥。Java提供了丰富的并发工具类,如Thread、Runnable以及ExecutorService,这些都是进行...

    java并发集合

    Java并发集合中最核心的几个类包括: 1. **ConcurrentHashMap**:线程安全的哈希映射表,它比synchronized的Hashtable或Collections.synchronizedMap()包装的HashMap有更高的并发性能。ConcurrentHashMap采用了分段...

    Java并发编程与高并发解决方案(高清视频教程).rar

    Java并发编程是Java开发语言中的一个关键领域,特别是在构建高性能、高并发的后端系统时。Apache作为流行的开源软件框架,提供了许多与并发处理相关的工具和库,使得开发者能够更有效地管理和优化多线程环境。本教程...

    《java并发编程实践》

    《Java并发编程实践》这本书是Java开发者深入了解并发编程的重要参考资料,尤其对于想要提升在多线程环境下编程技能的程序员来说,它提供了丰富的实践经验和深入的理论解析。在Java的世界里,多线程是构建高性能、高...

    《Java并发编程艺术》高清带目录中文版

    《Java并发编程艺术》是一本深入探讨Java平台上的并发编程技术的专业书籍。这本书全面覆盖了Java并发编程的基础知识、核心概念以及高级技巧,旨在帮助读者理解如何在多线程环境中编写高效、安全的代码。 并发编程是...

    java并发编程实践中文版和英文版

    5. **并发设计模式**:书中有专门章节介绍了几种常见的并发设计模式,如生产者消费者模式、工作窃取模式、线程池等,以及如何避免和解决并发编程中常见的问题,如死锁、活锁和饥饿。 6. **并发性能优化**:在性能...

Global site tag (gtag.js) - Google Analytics