- 浏览: 455790 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
飞天奔月:
我来个简单点的代码 使用 LinkedHashSetpubli ...
ArrayList去重 -
飞天奔月:
public static <T> List< ...
ArrayList去重 -
aaron7524:
事务隔离级别 -
月陨殇:
wlh269 写道rswh110 写道lz内容写的不错,就是略 ...
事务隔离级别 -
lnx1824:
我的更奇怪,在本地静态的可以,放jetty里的页面后就不然,都 ...
JS得到上传图片尺寸
sleep() 和 wait() 有什么区别? 搞线程的最爱
sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级 (b)正在运行的线程因为其它原因而阻塞。
wait()是线程交互时,如果线程对一个同步对象(方法)x 发出一个wait()调用,该线程会暂停执行,被调对象(方法)进入等待状态,直到被唤醒或等待时间到。
Wait时别的线程可以访问锁定对象(调用wait,锁就撒手);
调用wait方法的时候必需锁定该对象;
Object提供的方法
Sleep时别的线程也不可以访问锁定对象(睡着也抱着锁);
Thread提供的方法
请参考下面2个例子就全明白了......
同步:
a.每个对象只有一把锁
b.一个线程访问同步方法时候,别的线程可以访问该对象的其他非同步的方法,而且也可以影响同步方法内部的变量。
例1:
例2:范例名称:生产者--消费者问题
遇到互斥的问题时候如何解决得呢?
答:将互斥的2个操作放到同一个类的2个方法中,然后让这2个方法都加上synchronized关键字修饰
/* * 源文件名称:SyncTest.java
* 要 点:
* 1. 共享数据的不一致性/临界资源的保护
* 2. Java对象锁的概念
* 3. synchronized关键字/wait()及notify()方法
*/
死锁:当一个或多个进程等待系统资源,而系统资源又同时被此进程本身或者其它进程占用
例:结果2个线程谁都不打印输出数据
Join方法:将某个子线程合并到主线程,即等子线程全部运行全部执行完之后才执行主线程
例1:
备注:子线程和主线程交替执行
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
例2:在 t1.start()子线程就绪;之后添加t1.join(),则等t1线程执行完之后才执行主线程
输出结果:
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
Yeild方法:当前线程让出CPU的时间给其他线程执行一会。注意:是让出一会儿,待会又回来了。。。
输出结果:只要一个线程执行到10的整数倍,必然让出CPU的时间给其他线程执行一会
t1: 1
t1: 2
t1: 3
t1: 4
t1: 5
t1: 6
t1: 7
t1: 8
t1: 9
t1: 10
t2: 1
t2: 2
t2: 3
t2: 4
t2: 5
t2: 6
t2: 7
t2: 8
t2: 9
t2: 10
t1: 11
t1: 12
t1: 13
t1: 14
t1: 15
t1: 16
t1: 17
t1: 18
t1: 19
t1: 20
t2: 11
t2: 12
t2: 13
t2: 14
t2: 15
...........
..............
...................
sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级 (b)正在运行的线程因为其它原因而阻塞。
wait()是线程交互时,如果线程对一个同步对象(方法)x 发出一个wait()调用,该线程会暂停执行,被调对象(方法)进入等待状态,直到被唤醒或等待时间到。
Wait时别的线程可以访问锁定对象(调用wait,锁就撒手);
调用wait方法的时候必需锁定该对象;
Object提供的方法
Sleep时别的线程也不可以访问锁定对象(睡着也抱着锁);
Thread提供的方法
请参考下面2个例子就全明白了......
同步:
a.每个对象只有一把锁
b.一个线程访问同步方法时候,别的线程可以访问该对象的其他非同步的方法,而且也可以影响同步方法内部的变量。
例1:
public class TT implements Runnable { int b = 100; public synchronized void m1() throws Exception{ b = 1000; Thread.sleep(1000); System.out.println("b = " + b); } public synchronized void m2() throws Exception { Thread.sleep(3000); b = 2000; } public void run() { try { m1(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TT tt = new TT(); Thread t = new Thread(tt); t.start(); tt.m2(); System.out.println(tt.b); } } ===输出结果有2中可能==== 如果主线程锁定当前对象,输出结果为: 2000 b = 1000 如果子线程锁定当前对象,输出结果为: 1000 b = 1000
例2:范例名称:生产者--消费者问题
遇到互斥的问题时候如何解决得呢?
答:将互斥的2个操作放到同一个类的2个方法中,然后让这2个方法都加上synchronized关键字修饰
/* * 源文件名称:SyncTest.java
* 要 点:
* 1. 共享数据的不一致性/临界资源的保护
* 2. Java对象锁的概念
* 3. synchronized关键字/wait()及notify()方法
*/
package com.wlh; public class ProduceConsumer { public static void main(String args[]){ SyncStack stack = new SyncStack(); Runnable p=new Producer(stack); Runnable c = new Consumer(stack); Thread t1 = new Thread(p); Thread t2 = new Thread(c); t1.start(); t2.start(); } } /** * 支持多线程同步操作的堆栈的实现 * 因为只有一个线程能够锁定当前对象,而同步方法的执行前先锁定当前对象, * 所以同一时刻,同步方法push和pop只能有一个在执行 * @author wulihai */ class SyncStack{ private int index = 0; private char []data = new char[6]; public synchronized void push(char c){ if(index == data.length){ try{ this.wait(); }catch(InterruptedException e){} } this.notify(); data[index] = c; index++; } public synchronized char pop(){ if(index ==0){ try{ this.wait(); }catch(InterruptedException e){} } this.notify(); index--; return data[index]; } } class Producer implements Runnable{ SyncStack stack; public Producer(SyncStack s){ stack = s; } public void run(){ for(int i=0; i<20; i++){ char c =(char)(Math.random()*26+'A');// stack.push(c); System.out.println("produced:"+c); try{ Thread.sleep((int)(Math.random()*1000)); //随机休息,这样看起来生产和消费的产品个数都是随机的 }catch(InterruptedException e){ } } } } class Consumer implements Runnable{ SyncStack stack; public Consumer(SyncStack s){ stack = s; } public void run(){ for(int i=0;i<20;i++){ char c = stack.pop(); System.out.println("消费:"+c); try{ Thread.sleep((int)(Math.random()*1000));//随机休息,这样看起来生产和消费的产品个数都是随机的 }catch(InterruptedException e){ } } } }
死锁:当一个或多个进程等待系统资源,而系统资源又同时被此进程本身或者其它进程占用
例:结果2个线程谁都不打印输出数据
package com.wlh; public class DeadLock extends Thread { int flag=0; static Object o1=new Object(); static Object o2=new Object(); public DeadLock(int flag){ this.flag=flag; } @Override public void run() { if(this.flag==1){ synchronized(o1){ System.out.println(Thread.currentThread().getName()+"锁定对象o1"); try { Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o2 } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o2){ System.out.print("this.flag="+this.flag); } } } if(this.flag==2){ synchronized(o2){ System.out.println(Thread.currentThread().getName()+"锁定对象o2"); try { Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o1 } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o1){ System.out.print("this.flag="+this.flag); } } } } public static void main(String []args){ DeadLock d1=new DeadLock(1); DeadLock d2=new DeadLock(2); d1.start(); d2.start(); } }
Join方法:将某个子线程合并到主线程,即等子线程全部运行全部执行完之后才执行主线程
例1:
package com.wlh; public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2("子线程"); t1.start(); /* try { t1.join(); } catch (InterruptedException e) {}*/ for(int i=1;i<=10;i++){ try { Thread.sleep(1000);//当前线程休息1000秒 System.out.println("i am main thread"); } catch (InterruptedException e) { e.printStackTrace(); } } } } class MyThread2 extends Thread { MyThread2(String s){ super(s); } public void run(){ for(int i =1;i<=10;i++){ System.out.println("i am "+getName()); try { sleep(1000);//当前线程休息1000秒 } catch (InterruptedException e) { return; } } } }
备注:子线程和主线程交替执行
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
例2:在 t1.start()子线程就绪;之后添加t1.join(),则等t1线程执行完之后才执行主线程
package com.wlh; public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2("子线程"); t1.start(); try { t1.join(); } catch (InterruptedException e) {} for(int i=1;i<=10;i++){ try { Thread.sleep(1000);//当前线程休息1000秒 System.out.println("i am main thread"); } catch (InterruptedException e) { e.printStackTrace(); } } } } class MyThread2 extends Thread { MyThread2(String s){ super(s); } public void run(){ for(int i =1;i<=10;i++){ System.out.println("i am "+getName()); try { sleep(1000);//当前线程休息1000秒 } catch (InterruptedException e) { return; } } } }
输出结果:
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
Yeild方法:当前线程让出CPU的时间给其他线程执行一会。注意:是让出一会儿,待会又回来了。。。
package com.wlh; public class TestYield { public static void main(String[] args) { MyThread3 t1 = new MyThread3("t1"); MyThread3 t2 = new MyThread3("t2"); t1.start(); t2.start(); } } class MyThread3 extends Thread { MyThread3(String s){super(s);} public void run(){ for(int i =1;i<=100;i++){ System.out.println(getName()+": "+i); if(i%10==0){ yield(); } } } }
输出结果:只要一个线程执行到10的整数倍,必然让出CPU的时间给其他线程执行一会
t1: 1
t1: 2
t1: 3
t1: 4
t1: 5
t1: 6
t1: 7
t1: 8
t1: 9
t1: 10
t2: 1
t2: 2
t2: 3
t2: 4
t2: 5
t2: 6
t2: 7
t2: 8
t2: 9
t2: 10
t1: 11
t1: 12
t1: 13
t1: 14
t1: 15
t1: 16
t1: 17
t1: 18
t1: 19
t1: 20
t2: 11
t2: 12
t2: 13
t2: 14
t2: 15
...........
..............
...................
发表评论
-
java开发实战视频详解
2017-07-02 08:09 510java开发实战视频详解 链接: http://pan.bai ... -
ArrayList去重
2013-04-25 10:18 3294public static List removeDuplic ... -
java ArrayList 自定义排序
2013-04-22 11:39 2159import java.util.ArrayList; imp ... -
按照指定编码读取配置文件
2012-12-13 10:17 895BufferedReader reader = new Buf ... -
java读取系统编码
2012-12-13 09:45 896public static void main(String[ ... -
Axis2和现有项目的集成
2011-08-11 10:08 1398axis2和现有项目集成 1.下载axis2-1.5-war. ... -
阻塞队列
2010-09-03 08:54 1226ArrayBlockingQueue为阻塞队列,加入和取出元素 ... -
axis2和JDK1.5开发(文件传输服务)详解二(图解)
2010-06-28 16:36 22925.生成webservice服务端代 ... -
产生随机字符串
2010-05-05 17:13 1061import java.util.Random; p ... -
常用IO操作
2009-09-22 13:22 1306例子:写文件,在文件末尾追加文字并且指定输出文件内容字符编码为 ... -
FileChannel锁定文件
2009-09-22 10:52 2415当FileLock fl = fc.tryLock();执行成 ... -
SOCKET 文件传输
2009-09-21 15:47 4250要求将服务端文件夹A下的文件拷贝到客户端文件A下 删除服务端文 ... -
ZIP 压缩 和解压缩
2009-09-21 15:40 1125package com.socket.zip.util; ... -
Oracle number类型查询精度丢失问题
2009-08-21 16:00 6792一、需求中要求查到一个字段的值然后保持小数点后2位 ... -
Oracle number类型数据取出来后四舍五入到小数点后2位
2009-08-19 10:46 8128package com.wlh.test; impo ... -
将汉字编码为unicode
2009-07-28 10:26 888package test; import java. ... -
验证码
2009-07-05 17:29 1283验证servlet: package edu.yale. ... -
java.util.Date对象和String对象转换 SimpleDateFormat
2009-06-30 15:35 3068import java.text.ParseExcept ... -
Socket高级编程 多客户端
2009-06-26 14:03 2566客户端: package com.wlh.test; ... -
进制转换
2009-06-18 12:48 115716进制和字符串之间转换--- import java ...
相关推荐
然而,多线程也带来了数据同步的问题,因为多个线程可能同时访问共享资源,如果不加以控制,就可能导致数据不一致或引发错误。本篇文章将深入探讨三种在C++中实现多线程同步的方法:事件对象、关键代码段和互斥对象...
在处理多线程时,有几个关键概念和特性需要理解: - **线程同步**:为了避免线程间的冲突,需要同步对共享资源的访问。C#提供了`Mutex`, `Semaphore`, `Monitor`, `lock`等机制。 - **线程优先级**:每个线程都有...
易语言,作为一款中国本土的、面向初学者和专业开发者都友好的编程工具,同样支持多线程编程。本节将详细讨论如何在易语言中实现多线程以及多次启动同一个子程序。 一、易语言简介 易语言是一种以中文作为编程语句...
本文将详细讲解Java中线程的几个关键方法及其应用场景。 1. `run()`方法 `run()`方法是线程执行的主要逻辑所在。当创建一个线程并调用`start()`方法时,Java虚拟机(JVM)会自动调用`run()`方法。`run()`方法必须是`...
多线程编程涉及到几个关键概念: 1. **线程同步**:当多个线程访问同一资源时,可能导致数据不一致。为此,可以使用锁(Mutex, Semaphore, Monitor等)或者`lock`关键字来确保同一时间只有一个线程访问共享资源。 2....
在多线程编程中,有以下几个关键概念: 1. 线程安全:当多个线程访问同一数据时,如果代码能保证数据的完整性和一致性,那么我们就说这个代码是线程安全的。为了实现线程安全,通常需要使用锁(如互斥量、信号量)或...
多线程在按键精灵中的应用主要体现在以下几个方面: 1. **并行执行任务**:通过开启多个线程,按键精灵能够同时处理不同的任务,例如在一个线程中打开应用程序,另一个线程执行特定的点击或输入操作,这使得自动化...
本文将详细介绍几种在VBS中模拟多线程的方法,并探讨它们的应用场景和技术细节。 #### 1. 使用WScript.Shell.Run模拟并发执行 VBS可以通过`WScript.Shell.Run`方法来启动其他进程或脚本,从而达到模拟多线程的效果...
在多线程访问网页的场景中,通常涉及到以下几个关键知识点: 1. **线程基础**:线程是操作系统调度的基本单位,一个进程可以包含多个线程。在易语言中,通过创建和管理线程,可以并发地执行多个任务。创建线程的...
在服务器端的多线程实现中,我们使用while循环不断地监听客户端的连接请求,并在accept方法中创建一个新的ClientThread对象,以便处理客户端的连接请求。 多线程Socket服务器端程序的优点 使用C#语言开发多线程...
总结来说,易语言的多线程编程涉及以下几个关键知识点: 1. **创建和结束线程**:使用易语言提供的指令创建和结束线程。 2. **参数传递**:通过函数参数将数据传递给线程,可以是基本类型、结构体或引用类型。 3. *...
标题"e语言几个简单多线程写法"表明本文将探讨如何在e语言(可能指的是Erlang或者一种类似的编程语言)中实现多线程编程,适用于初学者。描述中提到“新手可以参考源码多学习一下,我也是在学习中”,暗示我们将分享...
多线程是指一个应用程序内同时运行多个独立的执行线程。在C#中,可以使用`System.Threading`命名空间中的`Thread`类创建和管理线程。通过开启新线程,我们可以让CPU在处理一项任务的同时进行其他任务,提高程序的...
单线程的优势主要体现在以下几个方面: 1. **简化程序设计**:由于无需处理多线程间的竞争条件或死锁等问题,因此程序设计更加简单明了。 2. **易于调试**:单线程程序的调试相对容易,因为不存在多个线程之间复杂的...
多线程编程有以下几个优点: 1. 提高程序的执行效率:多线程编程可以同时执行多个任务,从而提高程序的执行效率。 2. 提高程序的响应速度:多线程编程可以提高程序的响应速度,因为它可以同时执行多个任务。 3. ...
一个简单的多线程程序通常包括以下几个步骤: 1. **创建线程**:创建新线程时,我们需要传递一个可调用对象(如函数或函数对象)以及其可能的参数。例如,我们可以定义一个函数`void threadFunction(int arg)`,...
标题 "一个多线程下载程序" 描述了一个使用VC++编程语言实现的软件,该软件能够通过多线程技术加速文件的下载过程。多线程下载是现代互联网应用程序中常见的优化技术,尤其对于大文件下载,它能显著提高下载速度,...
在E语言中,创建一个新的线程通常涉及到以下几个步骤: 1. 引入线程库:首先,你需要确保E语言支持多线程,并正确引入相关的库或模块。 2. 定义线程函数:创建一个函数,该函数将作为新线程的执行体。 3. 创建线程:...
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
为了解决这些问题,文章介绍了一种基于Linux下的多线程服务器程序设计方法。 多线程服务器程序设计的优点是可以解决传统服务器工作方式的三个缺点。首先,创建线程比创建进程快10~100倍,能快速地响应客户请求。...