- 浏览: 272011 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (133)
- GWT (7)
- IT生活 (9)
- JAVA综合 (38)
- Servlet (5)
- vaadin (2)
- About Eclipse (2)
- StarUML (1)
- Spring (7)
- ibatis (3)
- web (35)
- ExtJs (2)
- Quartz (13)
- Struts (1)
- 学习XML (6)
- io流 (2)
- web应用之压缩 (3)
- Spring MVC (0)
- Velocity (5)
- 静态代码分析工具 (2)
- 观点 (1)
- JUnit (3)
- jQuery (4)
- mysql (2)
- javascript (16)
- linux (4)
- pattern (1)
- java加密技术 (2)
最新评论
-
tan4836128:
确实不行,我的1.8.5,降到1.6.2也不行,楼主的情况很局 ...
Spring调用Quartz定时任务报Couldn't store trigger异常 -
alfusen_xiong:
有没有自动注入的方法可以取代executeInternal() ...
Quartz任务中调用Spring容器中bean及动态调度任务 -
luoxiang183:
换了也不行啊
Spring调用Quartz定时任务报Couldn't store trigger异常 -
liubey:
首先谢谢LZ的文章,其实我想问个问题,既然有心做成工具类,就最 ...
对象和map转换 -
小林夕:
几年前用还行,现在做UML一般都开始使用在线作图工具了,可以了 ...
StarUML简介
1. 有两种方法可以创建并运行一个线程:
•继承Thread类并覆盖Run方法,Run中的代码就在另一个线程执行。
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 调用下面代码,线程开始运行
04. start();
05. }
06.
07. @Override
08. public void run() {
09. // 这里的代码是在线程中执行的
10. int i = 0;
11. while (i < 20)
12. {
13. System.out.println(i);
14. try {
15. sleep(100);
16. } catch (InterruptedException e) {
17. // TODO Auto-generated catch block
18. e.printStackTrace();
19. }
20. ++i;
21. }
22. }
23.}
24.
25.public class Main {
26. public static void main(String[] args) {
27. MyThread myThread = new MyThread();
28. }
29.}
class MyThread extends Thread {
MyThread() {
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
++i;
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
}
}
•实现Runnable接口并传给新建的Thread类,实现类的Run方法即在另一个线程执行。
view plaincopy to clipboardprint?
01.// 实现Runnable接口
02.public class Main implements Runnable {
03. @Override
04. public void run() {
05. // 这里的代码是在线程中执行的
06. int i = 0;
07. while (i < 20)
08. {
09. System.out.println(i);
10. try {
11. Thread.sleep(100);
12. } catch (InterruptedException e) {
13. // TODO Auto-generated catch block
14. e.printStackTrace();
15. }
16. ++i;
17. }
18. }
19.
20. public static void main(String[] args) {
21. Main runable = new Main();
22. new Thread(runable).start();
23. }
24.}
// 实现Runnable接口
public class Main implements Runnable {
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
++i;
}
}
public static void main(String[] args) {
Main runable = new Main();
new Thread(runable).start();
}
}
2. 后台线程(daemon)不属于程序不可或缺的一部分,当程序存在非后台线程时,程序就不会终止;而如果非后台线程都结束了,此时不管有没有后台线程,程序都可以随时终止。要设定一个线程为后台线程,可以调用Thread.setDaemon(true),在一个后台线程中创建其他线程,这些线程也自动被设为后台线程:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 把该线程设为后台线程
04. setDaemon(true);
05. // 调用下面代码,线程开始运行
06. start();
07. }
08.
09. @Override
10. public void run() {
11. // 这里的代码是在线程中执行的
12. int i = 0;
13. while (i < 20)
14. {
15. System.out.println(i);
16. try {
17. sleep(100);
18. } catch (InterruptedException e) {
19. e.printStackTrace();
20. }
21. ++i;
22. }
23. }
24.}
25.
26.public class Main{
27. public static void main(String[] args) {
28. MyThread mythread = new MyThread();
29. // mythread.run还没有执行完就结束程序了
30. }
31.}
32.// 程序只打印了0就结束了,而前面的例子程序会打印到19为止
class MyThread extends Thread {
MyThread() {
// 把该线程设为后台线程
setDaemon(true);
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
++i;
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mythread = new MyThread();
// mythread.run还没有执行完就结束程序了
}
}
// 程序只打印了0就结束了,而前面的例子程序会打印到19为止
3. 在上面的例子中,如何让主线程等到后台线程结束时才结束呢?答案是调用后台线程的jion()方法,可以传入一个超时参数,如果不传则表示一直等到后台线程结束才返回:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 把该线程设为后台线程
04. setDaemon(true);
05. // 调用下面代码,线程开始运行
06. start();
07. }
08.
09. @Override
10. public void run() {
11. // 这里的代码是在线程中执行的
12. int i = 0;
13. while (i < 20)
14. {
15. System.out.println(i);
16. try {
17. sleep(100);
18. } catch (InterruptedException e) {
19. e.printStackTrace();
20. }
21. ++i;
22. }
23. }
24.}
25.
26.public class Main{
27. public static void main(String[] args) {
28. MyThread mythread = new MyThread();
29. try {
30. // 等待后台线程结束
31. mythread.join();
32. } catch (InterruptedException e) {
33. e.printStackTrace();
34. }
35. }
36.}
class MyThread extends Thread {
MyThread() {
// 把该线程设为后台线程
setDaemon(true);
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
++i;
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mythread = new MyThread();
try {
// 等待后台线程结束
mythread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4. 当两个线程同时读写同一份数据时,可能会引起资源冲突,这时就需要在并行机制之外,再提供一种同步机制,使对数据的读写可以有序的进行,Java对此的处理非常简单,就是使用synchronized关键字:
•在普通方法前面加上synchronized,使得这个方法变成同步方法,先看下面例子,当主线程和工作线程同时调用synProc时,谁先调用到,谁就获得一个锁,另外一个只能等待,这样就保持在多线程环境下调用这个方法是有序的:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. synchronized public void synProc(){
12. int count = 0;
13. while (count++ < 10) {
14. try {
15. sleep(100);
16. System.out.println("synProc: " + count);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. }
21. }
22.}
23.
24.public class Main{
25. public static void main(String[] args) {
26. MyThread thread = new MyThread();
27. thread.synProc();
28. }
29.}
30.// 输出结果是:
31.synProc: 1
32.synProc: 2
33.synProc: 3
34.synProc: 4
35.synProc: 5
36.synProc: 6
37.synProc: 7
38.synProc: 8
39.synProc: 9
40.synProc: 10
41.synProc: 1
42.synProc: 2
43.synProc: 3
44.synProc: 4
45.synProc: 5
46.synProc: 6
47.synProc: 7
48.synProc: 8
49.synProc: 9
50.synProc: 10
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
synchronized public void synProc(){
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc();
}
}
// 输出结果是:
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
•其实synchronized方法是在对象级别上的,每个对象都有一个锁,当调用它的任意一个同步方法时,就是去获得这个对象锁,当获得对象锁时,其他同步方法也不能同时被调用了,只能等这个方法执行完才可以被调用,下面代码清楚地说明这一点:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. synchronized public void synProc(){
12. int count = 0;
13. while (count++ < 10) {
14. try {
15. sleep(100);
16. System.out.println("synProc: " + count);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. }
21. }
22.
23. synchronized public void synProc2() {
24. int count = 0;
25. while (count++ < 10) {
26. try {
27. sleep(100);
28. System.out.println("synProc2: " + count);
29. } catch (InterruptedException e) {
30. e.printStackTrace();
31. }
32. }
33. }
34.}
35.
36.public class Main{
37. public static void main(String[] args) {
38. MyThread thread = new MyThread();
39. thread.synProc2();
40. }
41.}
42.// 输出
43.synProc2: 1
44.synProc2: 2
45.synProc2: 3
46.synProc2: 4
47.synProc2: 5
48.synProc2: 6
49.synProc2: 7
50.synProc2: 8
51.synProc2: 9
52.synProc2: 10
53.synProc: 1
54.synProc: 2
55.synProc: 3
56.synProc: 4
57.synProc: 5
58.synProc: 6
59.synProc: 7
60.synProc: 8
61.synProc: 9
62.synProc: 10
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
synchronized public void synProc(){
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized public void synProc2() {
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc2: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc2();
}
}
// 输出
synProc2: 1
synProc2: 2
synProc2: 3
synProc2: 4
synProc2: 5
synProc2: 6
synProc2: 7
synProc2: 8
synProc2: 9
synProc2: 10
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
•synchronized可以加到静态方法前面,每个类也有一个锁,调用同步静态方法就是获得类级别的锁,这使类中的所有同步静态方法变得有序,即只有一个同步静态方法被调用,其他的同步静态就只好等待它结束才能被调用。
•synchronized还可以加在方法之内,称为同步块,如synchronized(obj){...}这样的语法,这里其实是获得obj对象的锁,因此Obj的同步方法也会受它影响,即对于Obj的同步块被执行时,Obj的同步方法必须等同步块执行完才能被调用:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. public void synProc(){
12. int count = 0;
13. synchronized (this) {
14. do {
15. try {
16. sleep(50);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. System.out.println("synProc :" + count);
21. } while (count++ < 3);
22. }
23. }
24.
25. synchronized public void synProc2() {
26. int count = 0;
27. do {
28. try {
29. sleep(50);
30. } catch (InterruptedException e) {
31. e.printStackTrace();
32. }
33. System.out.println("synProc2 :" + count);
34. } while (count++ < 3);
35. }
36.}
37.
38.public class Main{
39. public static void main(String[] args) {
40. MyThread thread = new MyThread();
41. thread.synProc2();
42. }
43.}
44.// 输出:
45.synProc2 :0
46.synProc2 :1
47.synProc2 :2
48.synProc2 :3
49.synProc :0
50.synProc :1
51.synProc :2
52.synProc :3
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
public void synProc(){
int count = 0;
synchronized (this) {
do {
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synProc :" + count);
} while (count++ < 3);
}
}
synchronized public void synProc2() {
int count = 0;
do {
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synProc2 :" + count);
} while (count++ < 3);
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc2();
}
}
// 输出:
synProc2 :0
synProc2 :1
synProc2 :2
synProc2 :3
synProc :0
synProc :1
synProc :2
synProc :3
5. 线程之间的等待与通知通过wait和notify,notifyAll来实现。
•这三个方法都必须在对象的同步块中执行,否则运行期会出现IllegalMonitorStateException异常。
•当线程A调用Obj.wait()时,A将被挂起,直到另一个线程B调用Obj.notify()或Obj.notifyAll(),A才被重新唤醒。
•如果只有一个线程调用Obj.wait(),另一个线程只需要调用Obj.notify()即可;但如果有多个线程调用Obj.wait(),则另一个线程必须调用Obj.notifyAll()才可以将所有的线程唤醒。
下面代码演示了一个writer和多个reader的协作过程:
view plaincopy to clipboardprint?
01.class Writer extends Thread {
02. private char chr;
03.
04. @Override
05. public void run() {
06. for (char c = 'A'; c <= 'Z'; ++c){
07. chr = c;
08. // 通知Reader可以读了
09. synchronized (this) {
10. notifyAll();
11. }
12. // 过会儿再写
13. try {
14. sleep(100);
15. } catch (InterruptedException e) {
16. e.printStackTrace();
17. }
18. }
19. }
20.
21. public char getChar() {
22. return chr;
23. }
24.}
25.
26.class Reader extends Thread {
27. private Writer writer;
28.
29. Reader(Writer writer) {
30. this.writer = writer;
31. start();
32. }
33.
34. @Override
35. public void run() {
36. while (true){
37. // 等待Writer写
38. synchronized (writer) {
39. try {
40. // 此处Reader线程将被挂起
41. writer.wait();
42. } catch (InterruptedException e) {
43. e.printStackTrace();
44. }
45. }
46. // 读取Writer写的内容
47. char chr = writer.getChar();
48. System.out.print(chr + " ");
49. // 读到Z即结束
50. if (chr == 'Z') {
51. System.out.println();
52. break;
53. }
54. }
55. }
56.}
57.
58.public class Main{
59. public static void main(String[] args) {
60. Writer writer = new Writer();
61. Reader reader1 = new Reader(writer);
62. Reader reader2 = new Reader(writer);
63. // 开始
64. writer.start();
65. }
66.}
67.// 最后的输出是:
68.A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z
69.Z
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/linzhengqun/archive/2011/04/02/6296458.aspx
•继承Thread类并覆盖Run方法,Run中的代码就在另一个线程执行。
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 调用下面代码,线程开始运行
04. start();
05. }
06.
07. @Override
08. public void run() {
09. // 这里的代码是在线程中执行的
10. int i = 0;
11. while (i < 20)
12. {
13. System.out.println(i);
14. try {
15. sleep(100);
16. } catch (InterruptedException e) {
17. // TODO Auto-generated catch block
18. e.printStackTrace();
19. }
20. ++i;
21. }
22. }
23.}
24.
25.public class Main {
26. public static void main(String[] args) {
27. MyThread myThread = new MyThread();
28. }
29.}
class MyThread extends Thread {
MyThread() {
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
++i;
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
}
}
•实现Runnable接口并传给新建的Thread类,实现类的Run方法即在另一个线程执行。
view plaincopy to clipboardprint?
01.// 实现Runnable接口
02.public class Main implements Runnable {
03. @Override
04. public void run() {
05. // 这里的代码是在线程中执行的
06. int i = 0;
07. while (i < 20)
08. {
09. System.out.println(i);
10. try {
11. Thread.sleep(100);
12. } catch (InterruptedException e) {
13. // TODO Auto-generated catch block
14. e.printStackTrace();
15. }
16. ++i;
17. }
18. }
19.
20. public static void main(String[] args) {
21. Main runable = new Main();
22. new Thread(runable).start();
23. }
24.}
// 实现Runnable接口
public class Main implements Runnable {
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
++i;
}
}
public static void main(String[] args) {
Main runable = new Main();
new Thread(runable).start();
}
}
2. 后台线程(daemon)不属于程序不可或缺的一部分,当程序存在非后台线程时,程序就不会终止;而如果非后台线程都结束了,此时不管有没有后台线程,程序都可以随时终止。要设定一个线程为后台线程,可以调用Thread.setDaemon(true),在一个后台线程中创建其他线程,这些线程也自动被设为后台线程:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 把该线程设为后台线程
04. setDaemon(true);
05. // 调用下面代码,线程开始运行
06. start();
07. }
08.
09. @Override
10. public void run() {
11. // 这里的代码是在线程中执行的
12. int i = 0;
13. while (i < 20)
14. {
15. System.out.println(i);
16. try {
17. sleep(100);
18. } catch (InterruptedException e) {
19. e.printStackTrace();
20. }
21. ++i;
22. }
23. }
24.}
25.
26.public class Main{
27. public static void main(String[] args) {
28. MyThread mythread = new MyThread();
29. // mythread.run还没有执行完就结束程序了
30. }
31.}
32.// 程序只打印了0就结束了,而前面的例子程序会打印到19为止
class MyThread extends Thread {
MyThread() {
// 把该线程设为后台线程
setDaemon(true);
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
++i;
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mythread = new MyThread();
// mythread.run还没有执行完就结束程序了
}
}
// 程序只打印了0就结束了,而前面的例子程序会打印到19为止
3. 在上面的例子中,如何让主线程等到后台线程结束时才结束呢?答案是调用后台线程的jion()方法,可以传入一个超时参数,如果不传则表示一直等到后台线程结束才返回:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. // 把该线程设为后台线程
04. setDaemon(true);
05. // 调用下面代码,线程开始运行
06. start();
07. }
08.
09. @Override
10. public void run() {
11. // 这里的代码是在线程中执行的
12. int i = 0;
13. while (i < 20)
14. {
15. System.out.println(i);
16. try {
17. sleep(100);
18. } catch (InterruptedException e) {
19. e.printStackTrace();
20. }
21. ++i;
22. }
23. }
24.}
25.
26.public class Main{
27. public static void main(String[] args) {
28. MyThread mythread = new MyThread();
29. try {
30. // 等待后台线程结束
31. mythread.join();
32. } catch (InterruptedException e) {
33. e.printStackTrace();
34. }
35. }
36.}
class MyThread extends Thread {
MyThread() {
// 把该线程设为后台线程
setDaemon(true);
// 调用下面代码,线程开始运行
start();
}
@Override
public void run() {
// 这里的代码是在线程中执行的
int i = 0;
while (i < 20)
{
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
++i;
}
}
}
public class Main{
public static void main(String[] args) {
MyThread mythread = new MyThread();
try {
// 等待后台线程结束
mythread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4. 当两个线程同时读写同一份数据时,可能会引起资源冲突,这时就需要在并行机制之外,再提供一种同步机制,使对数据的读写可以有序的进行,Java对此的处理非常简单,就是使用synchronized关键字:
•在普通方法前面加上synchronized,使得这个方法变成同步方法,先看下面例子,当主线程和工作线程同时调用synProc时,谁先调用到,谁就获得一个锁,另外一个只能等待,这样就保持在多线程环境下调用这个方法是有序的:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. synchronized public void synProc(){
12. int count = 0;
13. while (count++ < 10) {
14. try {
15. sleep(100);
16. System.out.println("synProc: " + count);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. }
21. }
22.}
23.
24.public class Main{
25. public static void main(String[] args) {
26. MyThread thread = new MyThread();
27. thread.synProc();
28. }
29.}
30.// 输出结果是:
31.synProc: 1
32.synProc: 2
33.synProc: 3
34.synProc: 4
35.synProc: 5
36.synProc: 6
37.synProc: 7
38.synProc: 8
39.synProc: 9
40.synProc: 10
41.synProc: 1
42.synProc: 2
43.synProc: 3
44.synProc: 4
45.synProc: 5
46.synProc: 6
47.synProc: 7
48.synProc: 8
49.synProc: 9
50.synProc: 10
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
synchronized public void synProc(){
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc();
}
}
// 输出结果是:
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
•其实synchronized方法是在对象级别上的,每个对象都有一个锁,当调用它的任意一个同步方法时,就是去获得这个对象锁,当获得对象锁时,其他同步方法也不能同时被调用了,只能等这个方法执行完才可以被调用,下面代码清楚地说明这一点:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. synchronized public void synProc(){
12. int count = 0;
13. while (count++ < 10) {
14. try {
15. sleep(100);
16. System.out.println("synProc: " + count);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. }
21. }
22.
23. synchronized public void synProc2() {
24. int count = 0;
25. while (count++ < 10) {
26. try {
27. sleep(100);
28. System.out.println("synProc2: " + count);
29. } catch (InterruptedException e) {
30. e.printStackTrace();
31. }
32. }
33. }
34.}
35.
36.public class Main{
37. public static void main(String[] args) {
38. MyThread thread = new MyThread();
39. thread.synProc2();
40. }
41.}
42.// 输出
43.synProc2: 1
44.synProc2: 2
45.synProc2: 3
46.synProc2: 4
47.synProc2: 5
48.synProc2: 6
49.synProc2: 7
50.synProc2: 8
51.synProc2: 9
52.synProc2: 10
53.synProc: 1
54.synProc: 2
55.synProc: 3
56.synProc: 4
57.synProc: 5
58.synProc: 6
59.synProc: 7
60.synProc: 8
61.synProc: 9
62.synProc: 10
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
synchronized public void synProc(){
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized public void synProc2() {
int count = 0;
while (count++ < 10) {
try {
sleep(100);
System.out.println("synProc2: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc2();
}
}
// 输出
synProc2: 1
synProc2: 2
synProc2: 3
synProc2: 4
synProc2: 5
synProc2: 6
synProc2: 7
synProc2: 8
synProc2: 9
synProc2: 10
synProc: 1
synProc: 2
synProc: 3
synProc: 4
synProc: 5
synProc: 6
synProc: 7
synProc: 8
synProc: 9
synProc: 10
•synchronized可以加到静态方法前面,每个类也有一个锁,调用同步静态方法就是获得类级别的锁,这使类中的所有同步静态方法变得有序,即只有一个同步静态方法被调用,其他的同步静态就只好等待它结束才能被调用。
•synchronized还可以加在方法之内,称为同步块,如synchronized(obj){...}这样的语法,这里其实是获得obj对象的锁,因此Obj的同步方法也会受它影响,即对于Obj的同步块被执行时,Obj的同步方法必须等同步块执行完才能被调用:
view plaincopy to clipboardprint?
01.class MyThread extends Thread {
02. MyThread() {
03. start();
04. }
05.
06. @Override
07. public void run() {
08. synProc();
09. }
10.
11. public void synProc(){
12. int count = 0;
13. synchronized (this) {
14. do {
15. try {
16. sleep(50);
17. } catch (InterruptedException e) {
18. e.printStackTrace();
19. }
20. System.out.println("synProc :" + count);
21. } while (count++ < 3);
22. }
23. }
24.
25. synchronized public void synProc2() {
26. int count = 0;
27. do {
28. try {
29. sleep(50);
30. } catch (InterruptedException e) {
31. e.printStackTrace();
32. }
33. System.out.println("synProc2 :" + count);
34. } while (count++ < 3);
35. }
36.}
37.
38.public class Main{
39. public static void main(String[] args) {
40. MyThread thread = new MyThread();
41. thread.synProc2();
42. }
43.}
44.// 输出:
45.synProc2 :0
46.synProc2 :1
47.synProc2 :2
48.synProc2 :3
49.synProc :0
50.synProc :1
51.synProc :2
52.synProc :3
class MyThread extends Thread {
MyThread() {
start();
}
@Override
public void run() {
synProc();
}
public void synProc(){
int count = 0;
synchronized (this) {
do {
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synProc :" + count);
} while (count++ < 3);
}
}
synchronized public void synProc2() {
int count = 0;
do {
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synProc2 :" + count);
} while (count++ < 3);
}
}
public class Main{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.synProc2();
}
}
// 输出:
synProc2 :0
synProc2 :1
synProc2 :2
synProc2 :3
synProc :0
synProc :1
synProc :2
synProc :3
5. 线程之间的等待与通知通过wait和notify,notifyAll来实现。
•这三个方法都必须在对象的同步块中执行,否则运行期会出现IllegalMonitorStateException异常。
•当线程A调用Obj.wait()时,A将被挂起,直到另一个线程B调用Obj.notify()或Obj.notifyAll(),A才被重新唤醒。
•如果只有一个线程调用Obj.wait(),另一个线程只需要调用Obj.notify()即可;但如果有多个线程调用Obj.wait(),则另一个线程必须调用Obj.notifyAll()才可以将所有的线程唤醒。
下面代码演示了一个writer和多个reader的协作过程:
view plaincopy to clipboardprint?
01.class Writer extends Thread {
02. private char chr;
03.
04. @Override
05. public void run() {
06. for (char c = 'A'; c <= 'Z'; ++c){
07. chr = c;
08. // 通知Reader可以读了
09. synchronized (this) {
10. notifyAll();
11. }
12. // 过会儿再写
13. try {
14. sleep(100);
15. } catch (InterruptedException e) {
16. e.printStackTrace();
17. }
18. }
19. }
20.
21. public char getChar() {
22. return chr;
23. }
24.}
25.
26.class Reader extends Thread {
27. private Writer writer;
28.
29. Reader(Writer writer) {
30. this.writer = writer;
31. start();
32. }
33.
34. @Override
35. public void run() {
36. while (true){
37. // 等待Writer写
38. synchronized (writer) {
39. try {
40. // 此处Reader线程将被挂起
41. writer.wait();
42. } catch (InterruptedException e) {
43. e.printStackTrace();
44. }
45. }
46. // 读取Writer写的内容
47. char chr = writer.getChar();
48. System.out.print(chr + " ");
49. // 读到Z即结束
50. if (chr == 'Z') {
51. System.out.println();
52. break;
53. }
54. }
55. }
56.}
57.
58.public class Main{
59. public static void main(String[] args) {
60. Writer writer = new Writer();
61. Reader reader1 = new Reader(writer);
62. Reader reader2 = new Reader(writer);
63. // 开始
64. writer.start();
65. }
66.}
67.// 最后的输出是:
68.A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z
69.Z
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/linzhengqun/archive/2011/04/02/6296458.aspx
发表评论
-
mysql中varchar类型转换Integer
2011-11-24 15:22 1178CAST(varchar字段 AS SIGNED) -
java 添加和清除cookie
2011-10-24 09:38 1988//添加cookie Cookie cookie = new ... -
java cookie操作
2011-10-24 09:34 1395Cookie概念: Cookie的格式实际上是一段纯文 ... -
java保留两位小数点(转)
2011-10-19 15:48 5662java保留两位小数问题: 方式一: 四舍五入 dou ... -
ibatis中批量删除
2011-09-15 10:27 1631Ibatis中批量删除方法: 方法一: 在映射文件中,按如 ... -
Java反射getFields()和getDeclaredFields()的区别
2011-09-05 13:23 1591Java反射 getFields()和getDeclaredF ... -
AES加密算法原理
2011-09-01 15:18 1666AES加密算法原理 随 ... -
Java AES加密实例
2011-09-01 14:30 3380package com.encrypt.hello; i ... -
Quartz任务中调用Spring容器中bean及动态调度任务
2011-08-31 15:09 19712Quartz 是开源任务调度框 ... -
Observer模式
2011-08-23 09:46 988Java深入到一定程度,就不可避免的碰到设计模式(design ... -
Java环境下Memcached应用详解(转)
2011-08-22 10:05 0本文将对在Java环境下Memcached应用进行详细介绍。M ... -
Spring容器详解(转)
2011-08-22 09:53 1230我们在使用ssh整合项目的时候,Spring在其中是一个非常重 ... -
Spring DI(依赖注入) IOC(控制反转) AOP(面向切面编程)
2011-08-22 09:43 2064spring 的优点? 1.降低了 ... -
11款用于优化、分析源代码的Java工具
2011-08-08 15:13 843本文将提供一些工具, ... -
Java编程中影响性能的一些特点
2011-08-08 15:04 728文中将提供一些在Java编程中影响性能的一些特点,为了能够提高 ... -
Velocity基础
2011-08-08 11:01 1755Velocity 基础 Velocity是一个基于java的 ... -
java io经典例子
2011-08-03 14:45 1108IO是JAVASE中非常重要的一块,是面向对象的完美体现,深入 ... -
JUnit4详细教程
2011-08-02 15:36 1182因jdk5中的新特性,JUn ... -
JUnit4注解
2011-08-02 15:31 975JUnit4注解 JUnit4的测试类不用再继承TestCa ... -
JUnit简明手册
2011-08-02 15:29 836用XP进行开发的过程,unit test是必不可少的环节。作为 ...
相关推荐
本资源致力于向您介绍 Java 并发编程中的线程基础,涵盖了多线程编程的核心概念、线程的创建和管理,以及线程间通信的基本方法。通过深入学习,您将建立扎实的多线程编程基础,能够更好地理解和应用多线程编程。 多...
用途: 学习Java语言的控制语法,掌握基础语法知识。 实验二: 关键词: Java的类 内容关键词: 类,Java实验 用途: 学习Java中的类的概念和使用,深入理解面向对象编程。 实验三: 关键词: 异常处理机制与数据流 内容...
Java开发基础--Java语言概述 Java语言概述 了解Java语言历史和特点 理解Java语言规范 能够区分API、JDK的含义 Java的发展历史 1991年,Sun公司James Gosling领导的Green小组创建了一种新型语言,命名为Oak(橡树),...
Java实验指导书_多线程 《Java语言程序设计基础教程》 上机实验指导手册 异常处理 【目的】 ①线程的创建和运行 ②Thread类的sleep、join等方法的使用 ③线程同步
【完整课程列表】 完整版 Java编程基础入门教程 ...完整版 Java编程基础入门教程 Java语言程序设计 第8章_多线程与异常处理(共72页).ppt 完整版 Java编程基础入门教程 Java语言程序设计 第9章_Applet(共40页).ppt
完整版 Java高级教程 Java语言程序设计 第2章 Java多线程(共24页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 哲学家的故事(共7页).ppt 完整版 Java高级教程 Java语言程序设计 第3章 Java网络基础知识(共...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...
完整版java基础入门教程由浅入深讲解 Java语言编程基础 第13章 多线程(共50页).ppt 完整版java基础入门教程由浅入深讲解 Java语言编程基础 第14章 网络通信(共76页).ppt 完整版java基础入门教程由浅入深讲解 ...
部分主要阐述Thread的基础知识,详细介绍线程的API使用、线程安全、线程间数据通信,以及如何保护共享资源等内容,它是深入学习多线程内容的基础。 第二部分引入了ClassLoader,这是因为ClassLoader与线程不无关系,...
Java语言基础 Java网络编程技术 Java程序设计使用教程 第07章 多线程(共44页).ppt Java语言基础 Java网络编程技术 Java程序设计使用教程 第08章 Applet应用程序(共34页).ppt Java语言基础 Java网络编程技术 Java...
本书是Java语言的经典教材,中文版分为《Java语言程序设计基础篇》和《Java语 言程序设计进阶篇》。基础篇从Java语言的特点入手,介绍了语法结构、面向对象程序 设计基础知识到面向对象程序设计、图形用户界面设计、...
【完整课程列表】 完整版 Java编程基础入门教程 ...完整版 Java编程基础入门教程 Java语言程序设计 第8章_多线程与异常处理(共72页).ppt 完整版 Java编程基础入门教程 Java语言程序设计 第9章_Applet(共40页).ppt
【完整课程列表】 完整版 Java编程基础入门教程 ...完整版 Java编程基础入门教程 Java语言程序设计 第8章_多线程与异常处理(共72页).ppt 完整版 Java编程基础入门教程 Java语言程序设计 第9章_Applet(共40页).ppt
完整版精品java课件 Java基础入门教程 Java程序设计 第2章 java语言基础(共31页).ppt 完整版精品java课件 Java基础入门教程 Java程序设计 第3章 控制结构(共23页).ppt 完整版精品java课件 Java基础入门教程 Java...
Unix操作系统环境下,应用程序可以利用fork... 可以说:Java语言对应用程序多线程能力的支持增强了Java作为网络程序设计语言的优势,为实现分布式应用系统中多客户端的并发访问以及提高服务器的响应效率奠定坚实基础。
支持并发编程:多线程编程是支持并发编程的基础,可以处理多个并发任务,如服务器处理多个客户端请求。 缺点: 竞态条件(Race Conditions):多个线程访问共享资源时可能引发竞态条件,导致数据不一致性和程序错误...
Java的基础知识点包括Java语言基础、面向对象、Java8新特性以及Java应用,其中Java语言基础包括环境搭建、基本数据类型、变量、常量定义、控制结构等,它们为学习编程语言打下了很好的基础;面向对象是任何编程语言...
随着现代处理器的生产工艺从提升...《Java多线程编程实战指南(核心篇)》适合有一定Java语言基础的读者作为入门多线程编程之用,也适合有一定多线程编程经验的读者作为重新梳理知识结构以提升认知层次和参考之用。
《Java高手真经(编程基础卷):Java核心编程技术》详细讲解了Java语言基础开发中的各种技术,主要内容包括如下。Java开发入门:JDK、JVM、Eclipse、Linux。Java语法基础:类、抽象类、接口、内部类、匿名类、异常、...
《Java高手真经(编程基础卷):Java核心编程技术》详细讲解了Java语言基础开发中的各种技术,主要内容包括如下。Java开发入门:JDK、JVM、Eclipse、Linux。Java语法基础:类、抽象类、接口、内部类、匿名类、异常、...