2个线程在同一个实例的方法中输出
会出现如下结果:
zhangxiaoxiang
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuomizhangxiaoxiang
ng
zhangxiaoxiang
lihuoming
zhangxiaoxiang
如下代码可以产生错误的结果:
1、2个线程同时访问,output方法一个线程没有允许完成另一个线程就进来。
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("lihuoming");
}
}
}).start();
}
class Outputer {
public void output(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
正确代码:
使用对象锁机制将输出体进行锁定
synchronized (this) { }
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("lihuoming");
}
}
}).start();
}
class Outputer {
public void output(String name) {
int len = name.length();
synchronized (this) {
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
2、错误代码
虽然两个线程调用的方法不同,可是还是在同一个对象中,当一个线程没有输出完毕的时候第二个线程就打印了
system.out.println();进行换行。
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output2("lihuoming");
}
}
}).start();
}
class Outputer {
public void output(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
public void output2(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
正确代码:
synchronized 关键字加在方法上默认锁定this 对象 如果在方法中需要 使用synchronized(this){}
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output2("lihuoming");
}
}
}).start();
}
static class Outputer {
public void output(String name) {
synchronized (this) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public synchronized void output2(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
错误代码:
因为一个线程调用的静态方法,即两个线程不是调用的同一个对象,也就说明synchronized不是锁定的同一个对象。
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Outputer.output3("lihuoming");
}
}
}).start();
}
static class Outputer {
public void output(String name) {
synchronized (this) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public static synchronized void output3(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
正确代码如下:
因为需要锁定静态对象 所以要使用Outputer.class
package cn.itcast.heima2;
public class TraditionalTreadSynchrorized {
public static void main(String[] args) {
new TraditionalTreadSynchrorized().init();
}
public void init() {
final Outputer output = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangxiaoxiang");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Outputer.output3("lihuoming");
}
}
}).start();
}
static class Outputer {
public void output(String name) {
synchronized (Outputer.class) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public static synchronized void output3(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
分享到:
相关推荐
资源名称:Java多线程与并发库高级应用视频教程22集资源目录:【】01传统线程技术回顾【】02传统定时器技术回顾【】03传统线程互斥技术【】04传统线程同步通信技术【】04传统线程同步通信技术_分割纪录【】05线程...
本文将深入探讨标题和描述中提到的“多线程的小例子”以及线程互斥的概念。 线程互斥是多线程编程中的一个关键概念,用于确保在特定时间内,只有一个线程可以访问共享资源,以防止数据不一致性和竞态条件。在C#中,...
张孝祥老师的课程"传智播客_张孝祥_传统线程同步通信技术"深入浅出地讲解了这一主题,旨在帮助开发者理解和掌握线程间的协作与数据共享方式。 线程同步是指在多线程环境下,控制多个线程按一定的顺序执行,以避免...
### 三、传统线程互斥技术 #### 3.1 互斥问题 在多线程环境中,多个线程可能同时访问共享资源(如银行账户余额),如果没有适当的控制措施,可能导致数据一致性问题或竞态条件。这种情况下,需要采取措施确保同一...
这个压缩包“C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)(0515).rar”包含了六个关于C#中多线程应用的实例,涵盖了从基础到高级的多线程使用场景,如线程创建、线程同步和互斥。...
在.NET框架中,C#语言提供了强大的多线程支持,使得开发者可以充分利用现代多核处理器的优势,实现并行处理和优化...学习并理解这些实例,将有助于开发者更好地在C#.NET项目中运用多线程技术,提高程序的性能和效率。
了解并熟练掌握这些传统线程同步通信技术,能帮助你在多线程编程中有效地避免数据竞争,提高程序的并发性和可靠性。在实际开发中,应根据具体需求选择最合适的同步机制,同时考虑线程同步带来的开销,以实现最佳性能...
本文将深入探讨传统线程同步通信技术,主要包括临界区、信号量、互斥量以及事件对象。 1. **临界区**(Critical Section) 临界区是程序中用于访问共享资源的代码段。为了防止多个线程同时进入临界区,我们可以...
传统线程互斥技术 - 线程间的互斥通常通过`synchronized`关键字或显式锁(`Lock`)来实现。 ##### 4. 传统线程同步通信技术 - 线程之间的同步通信可以通过`wait()`、`notify()`和`notifyAll()`等方法来实现。 #####...
在C++编程中,多线程技术是一种关键的并发处理机制,它允许程序同时执行多个独立的任务,从而提高系统的效率和响应性。本综合技术篇将深入探讨C++中的多线程概念、实现方法以及常见问题。 一、线程基础 线程是操作...
【Linux线程技术】在操作系统领域,Linux线程是指在Linux环境下实现的多线程编程技术。虽然在早期的Linux内核中并没有直接支持线程的概念,而是通过轻量级进程(Lightweight Process, LWP)来模拟线程的行为。在...
为了更高效地管理文件读取与进度更新过程,本篇文章将介绍如何利用线程同步技术中的互斥量(mutex)来实现这一功能。 #### 二、线程与进程基础知识 - **进程**:一个正在执行的应用程序及其资源集合,包括私有的虚拟...
除了传统的多线程,Delphi还支持异步编程模型,如使用IO Completion Ports(IOCP)来处理I/O密集型任务,提高系统吞吐量。IOCP允许系统在I/O操作完成时自动通知线程,避免了不必要的等待和上下文切换。 七、实际...
Java多线程编程技术是Java编程语言中一个非常重要的技术分支,它允许程序员在程序中创建多个执行流(线程),这些线程可以并发执行,从而使得程序能更加高效地利用系统资源,同时提高应用的响应速度和吞吐能力。...
Linux下的多线程不同于传统的进程创建,它通过克隆(`clone`)系统调用来创建线程,这种方法显著降低了CPU开销和内存消耗。克隆出的线程与父进程共享资源,例如文件、信号处理程序和虚拟内存,同时利用“写时复制”...
传统的同步套接字会在执行I/O操作时阻塞当前线程,直到操作完成,这可能会严重影响程序的响应速度。相比之下,异步套接字则能在数据到达时通过特定机制通知程序,从而使程序无需等待即可继续执行其他任务。 - **...
用户级线程完全由用户空间的程序实现和管理,包括线程调度、同步和互斥,这提供了更高的灵活性,适用于特定的应用场景,如实时处理、数据下载和采集。另一方面,内核级线程则由操作系统内核管理,通过系统调用来实现...