我想的有点杂,先写在说。
1,关于线程安全,如果一个方法里面全部是局部变量,那么是没有必要同步的,也就是说它是线程安全的。也就是不必加synchronized,servelet里面的的HttpServlet就是这样, PrintWriter out = response.getWriter();这句话中这个out流本来可以作为HttpServlet的类变量的,但是如果是那样就需要同步了,影响效率呀。
2,关于锁,
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.
比如: Test t = new Test();
线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.
作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.
也就是说在f1()前面加上synchronized ,那线程在调用这个方法的时候取得了这个对象的锁,也就是t的锁,
其他的线程想访问t的其他同步方法,比如f2()就不行,其实这样是不好的,很多时候我们用另外实例变量来锁。
class Test{
private static final Object obj=new Object();
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(obj){
//do something here
}
}
}
此时,如果一个线程访问f2,它拿到的是obj对象的锁,别的线程依然可以访问f1().
3,原子性,先看代码:
package com.test;
public class Test extends Thread {
private int a = 0;
private int b = 0;
public static void main(String[] args) {
Test test = new Test();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(test, "thread-" + i);
thread.start();
}
}
public synchronized void doWrite() {
a++;
try {
sleep((int)(Math.random()*100));
}
catch (Exception e) {
}
b++;
try {
sleep((int)(Math.random()*100));
}
catch (Exception e) {
}
}
public synchronized void print() {
System.out.println("" + Thread.currentThread().getName() + ":a:" + a);
System.out.println("" + Thread.currentThread().getName() + ":b:" + b);
}
public void run() {
f();
}
public synchronized void f() {
for (int i = 0; i < 5; i++) {
doWrite();
print();
}
}
}
输出结果:
thread-0:a:1
thread-0:b:1
thread-0:a:2
thread-0:b:2
thread-0:a:3
thread-0:b:3
thread-0:a:4
thread-0:b:4
thread-0:a:5
thread-0:b:5
thread-1:a:6
thread-1:b:6
thread-1:a:7
thread-1:b:7
thread-1:a:8
thread-1:b:8
thread-1:a:9
thread-1:b:9
thread-1:a:10
thread-1:b:10
thread-2:a:11
thread-2:b:11
thread-2:a:12
thread-2:b:12
thread-2:a:13
thread-2:b:13
thread-2:a:14
thread-2:b:14
thread-2:a:15
thread-2:b:15
thread-3:a:16
thread-3:b:16
thread-3:a:17
thread-3:b:17
thread-3:a:18
thread-3:b:18
thread-3:a:19
thread-3:b:19
thread-3:a:20
thread-3:b:20
thread-4:a:21
thread-4:b:21
thread-4:a:22
thread-4:b:22
thread-4:a:23
thread-4:b:23
thread-4:a:24
thread-4:b:24
thread-4:a:25
thread-4:b:25
thread-5:a:26
thread-5:b:26
thread-5:a:27
thread-5:b:27
thread-5:a:28
thread-5:b:28
thread-5:a:29
thread-5:b:29
thread-5:a:30
thread-5:b:30
thread-6:a:31
thread-6:b:31
thread-6:a:32
thread-6:b:32
thread-6:a:33
thread-6:b:33
thread-6:a:34
thread-6:b:34
thread-6:a:35
thread-6:b:35
thread-7:a:36
thread-7:b:36
thread-7:a:37
thread-7:b:37
thread-7:a:38
thread-7:b:38
thread-7:a:39
thread-7:b:39
thread-7:a:40
thread-7:b:40
thread-8:a:41
thread-8:b:41
thread-8:a:42
thread-8:b:42
thread-8:a:43
thread-8:b:43
thread-8:a:44
thread-8:b:44
thread-8:a:45
thread-8:b:45
thread-9:a:46
thread-9:b:46
thread-9:a:47
thread-9:b:47
thread-9:a:48
thread-9:b:48
thread-9:a:49
thread-9:b:49
thread-9:a:50
thread-9:b:50
我们可以看到是很标准的输出。
我们在run方法里面改点东西:
package com.test;
public class Test extends Thread {
private int a = 0;
private int b = 0;
public static void main(String[] args) {
Test test = new Test();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(test, "thread-" + i);
thread.start();
}
}
public synchronized void doWrite() {
a++;
try {
sleep((int)(Math.random()*100));
}
catch (Exception e) {
}
b++;
try {
sleep((int)(Math.random()*100));
}
catch (Exception e) {
}
}
public synchronized void print() {
System.out.println("" + Thread.currentThread().getName() + ":a:" + a);
System.out.println("" + Thread.currentThread().getName() + ":b:" + b);
}
public void run() {
for (int i = 0; i < 5; i++) {
doWrite();
print();
}
}
}
输出的结果就不确定了:
thread-0:a:10
thread-0:b:10
thread-1:a:10
thread-1:b:10
thread-2:a:10
thread-2:b:10
thread-3:a:10
thread-3:b:10
thread-4:a:10
thread-4:b:10
thread-5:a:10
thread-5:b:10
thread-6:a:10
thread-6:b:10
thread-7:a:10
thread-7:b:10
thread-8:a:10
thread-8:b:10
thread-9:a:10
thread-9:b:10
thread-0:a:20
thread-0:b:20
thread-1:a:20
thread-1:b:20
thread-2:a:20
thread-2:b:20
thread-3:a:20
thread-3:b:20
thread-4:a:20
thread-4:b:20
thread-5:a:20
thread-5:b:20
thread-6:a:20
thread-6:b:20
thread-7:a:20
thread-7:b:20
thread-8:a:20
thread-8:b:20
thread-9:a:20
thread-9:b:20
thread-0:a:30
thread-0:b:30
thread-1:a:30
thread-1:b:30
thread-2:a:30
thread-2:b:30
thread-3:a:30
thread-3:b:30
thread-4:a:30
thread-4:b:30
thread-5:a:30
thread-5:b:30
thread-6:a:30
thread-6:b:30
thread-7:a:30
thread-7:b:30
thread-8:a:30
thread-8:b:30
thread-9:a:30
thread-9:b:30
thread-0:a:40
thread-0:b:40
thread-1:a:40
thread-1:b:40
thread-2:a:40
thread-2:b:40
thread-3:a:40
thread-3:b:40
thread-4:a:40
thread-4:b:40
thread-5:a:40
thread-5:b:40
thread-6:a:40
thread-6:b:40
thread-7:a:40
thread-7:b:40
thread-8:a:40
thread-8:b:40
thread-9:a:40
thread-9:b:40
thread-0:a:50
thread-0:b:50
thread-1:a:50
thread-1:b:50
thread-2:a:50
thread-2:b:50
thread-3:a:50
thread-3:b:50
thread-4:a:50
thread-4:b:50
thread-5:a:50
thread-5:b:50
thread-6:a:50
thread-6:b:50
thread-7:a:50
thread-7:b:50
thread-8:a:50
thread-8:b:50
thread-9:a:50
thread-9:b:50
我们的目的就是要 完数据后在输出,所以应该确保这个过程的原子性。直接写在run方法里面就没能确保原子性。
先写到这,以后在加吧。
分享到:
相关推荐
Java同步与异步 Java同步与异步是Java编程中非常重要的概念,它们都是为了解决多线程环境中的线程安全问题。在多线程环境中,如果没有正确的同步机制,多个线程可能会同时访问共享资源,导致数据不一致和其他严重...
在Java编程语言中,同步(Synchronization)与异步(Asynchronization)是两个非常重要的概念,它们对于多线程处理和并发控制有着不可替代的作用。本文将深入探讨这两个概念的区别及其在Java中的具体应用。 #### 一...
在本文中,我们将讨论基于系统底层通信技术Socket 的JAVA IO同步和异步操作,包括阻塞(Blocking)和非阻塞(Non-Blocking)IO 操作。 同步(Synchronous)IO 同步IO 是指应用程序在执行IO 操作时,需要等待IO ...
### Java中的同步与异步详解 #### 一、同步与异步的概念理解 在软件开发领域,特别是针对并发处理和网络编程时,我们经常会遇到“同步”与“异步”这两个概念。简单来说: - **同步(Synchronous)**:指的是程序...
wait和notify方法是Java中最基本的同步机制,通过使用锁机制来实现异步调用转同步。下面是一个使用wait和notify方法的示例代码: ```java public class Demo1 extends BaseDemo { private final Object lock = ...
Java同步与异步 Java 同步与异步是一种编程技术,旨在解决多线程环境下的数据一致性和可见性问题。下面是 Java 同步与异步的定义和概念: 关键字: * thread(线程):Java 中的基本执行单元,能够独立执行一...
Java 同步、异步、阻塞和非阻塞分析 Java 中的同步、异步、阻塞和非阻塞是四个相关但不同的概念,它们都是在多线程编程中解决耗时操作的方法。在这里,我们将详细介绍这些概念之间的区别和联系。 同步...
JAVA邮件发送工具类(支持同步和异步发送邮件以及附件信息),支持多个抄送邮件发送。
Java中的同步和异步是两种不同的处理方式,它们在多线程编程中起着至关重要的作用,尤其是在构建高效、响应迅速的应用程序时。同步和异步的主要区别在于它们如何管理和控制对资源的访问以及任务的执行顺序。 同步...
今天,我们将详细介绍JAVA同步、异步、阻塞和非阻塞之间的区别。 同步和异步 同步和异步描述的是消息通信的机制。同步是指当一个request发送出去以后,会得到一个response,这整个过程就是一个同步调用的过程。...
Java同步与异步编程是多线程编程的核心内容,在Java中,线程同步与异步处理是保证程序正确执行的关键技术。本文将详细介绍Java中的线程同步机制、线程安全的实现以及异步执行的相关知识点。 首先,了解Java中的线程...
本篇文章将详细介绍如何使用Java的HttpClient实现异步请求资源。 首先,让我们了解什么是异步请求。在同步请求中,调用一个API或发送一个HTTP请求后,程序会等待响应返回,然后继续执行后续代码。而异步请求则不同...
总结来说,Socket异步和同步使用在C#编程中涉及的主要知识点包括: 1. **Socket基本概念**:理解Socket作为网络通信接口的作用,掌握其工作原理。 2. **同步与异步通信**:了解同步Socket阻塞的特点,以及异步...
本篇文章将深入探讨如何使用Java实现图片的异步和同步上传,并讲解如何实现在页面上即时回显。 首先,我们需要理解同步与异步的概念。在编程中,同步操作意味着一个任务执行完毕后才会执行下一个任务,而异步则允许...
总之,Java中的HTTP异步请求通过`HttpAsyncClients`和自定义的回调处理类,如`AsyncClientHttpExchangeStreaming`,提供了高效的网络通信能力,尤其适合大数据量、高并发的场景。理解和熟练运用这些技术,对于提升...
在Spring框架中,线程池的使用是实现并发和异步任务执行的关键工具。线程池的概念源于Java的`java.util.concurrent.ExecutorService`接口,它允许我们管理一组可重用的工作线程,以提高系统效率并减少资源消耗。...
在Java编程中,异步调用是一种非常重要的技术,它允许程序在等待某个耗时操作完成时继续执行其他任务,从而提高系统效率和响应性。本文将深入探讨如何使用Java来实现异步调用,以及它在后端开发中的应用。 1. **...
标签“多线程”强调了Java并发编程的核心概念,如线程的创建、同步、通信和状态管理。例如,`synchronized`关键字用于确保对共享资源的互斥访问,防止数据竞争;`wait()`, `notify()`和`notifyAll()`方法用于线程间...
Java中的半同步半异步模式旨在解耦并发系统中的异步和同步处理,提高效率和性能。该模式对于管理软件系统中的复杂并发操作特别有用。 ## 二、详细解释及实际示例 1. **实际示例**: - 想象一个繁忙的餐厅厨房,...