Java中的多线程(进修笔记)
添加时间:2013-5-18 点击量:
软件专业的大学生,立志成为法度媛,这学期才刚接触java,其实是够菜,高手们能指导一二,不堪感激感动。
今天学到了Java的多线程,下面是我做的笔记,仅供参考和复习。
- java的多线程:同时履行多个法度区块
- 启动线程:必须具备两个前提:
(1) 此类必须是延长自Thread类,使本身成为它的子类
(2) 线程的处理惩罚必须编写在run()办法中
注:Thread类存放在java.lang类库中,所以无需手动加载,调用start(),用以启动线程
3.实现Runnable接口来创建线程
因为Java不克不及多重持续,Java供给了Runnable接口,正好可以解决这个困难。接口中声明run()办法,只要在类中确切定义run()办法,就可以创建线程了。
下面是例子:
public class MyRunnable implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName());
//获得当前thread对象
然后在调用这个thread的 getName()办法。
}
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnable t1=new MyRunnable();
MyRunnable t2=new MyRunnable();
Thread th1=new Thread(t1,MyThread1);
Thread th2=new Thread(t2,MyThread2);
th1.start();
th2.start();
}
}
4.线程的经管
每一个线程,在其创建和灭亡之前,均会处于四种状况之一:新建的(newly created)、可运行的(runnable)、被冻结的(blocked)与灭亡的(dead);
当用new Thread()创建对象时,线程所处的便是这种状况,但此时体系并不会设备资料,直到用start()办法启动线程时才会设备;
当start()启动线程时,线程便进入可运行的状况,谁先抢到cpu,谁开端履行run()办法,其余的线程便在队列中守候机会争夺cpu资料;
当线程调用对象的wait() method 或该线程本身调用sleep(),冻结状况线程便产生。sleep(long millis)可用来设定睡眠的时候,millis毫秒(1/1000秒)。该线程和另一个线程join()在一路,则其他未启动的线程或法度代比及该线程停止后才会开端履行;
当线程被冻结时,便停止run()的履行,直到被冻结的身分消散,线程便回到可运行状况;
被冻结身分消散的原因可所以:
a,若是线程是用调用对象的wait()所冻结,则改对象的notify() 被调用时可解除冻结。(notify:告诉);
b,线程进入睡眠状况,但指定的时候到了。
当线程的run()履行停止,或调用了stop(),则线程进入灭亡状况。
举例:
1.若是要简单的设计线程的排序,可用join(),当某一线程调用join时,则其他线程会比及该线程停止后才开端履行,下面的例子,使得dog线程先完成后,再履行cat线程,比及线程履行停止后,再打印“Hello world;
//CTest.java
public class CTest extends Thread {
private String id;
public CTest(String str) {
id=str;
}
public void run() {
for(int i=0;i<4;i++)
{
try
{
sleep((int)(1000Math.random()));
}catch(InterruptedException e) {}
System.out.println(id+is running..);
}
}
}
//App2.java
public class App2 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CTest dog=new CTest(doggy);
CTest cat=new CTest(cat);
dog.start(); //启动dog线程
try
{
dog.join();//限制dog线程停止后才干往下履行
cat.start();//启动cat线程
cat.join(); //限制cat线程停止后才干往下履行
}
catch(InterruptedException e) {}
System.out.println(Hello World);
}
}
有没有重视到try...catch这段代码?这是因为,sleep()和join()必须写在try...catch里面,以捕获可能呈现的异常。
再来讲一下关于同步处理惩罚,先来举个例子: 假设有家银行,它可接管顾客的汇款,每做一次汇款,便可策画出汇款的总额,如今又两名顾客,每人分3次,每次100元将钱导入,最后银行汇款的总额应当为600元。
为解决这个题目,我们来写段代码:
//CBank.java
public class CBank {
private static int sum=0;
public static void add(int n)
{
int tmp=sum;
tmp=tmp+n;
try {
Thread.sleep((int)(1000Math.random()));
}
catch(InterruptedException e) {}
sum=tmp;
System.out.println(sum=+sum);
}
}
//CCustomer.java
public class CCustomer extends Thread {//顾客类,持续自Thread类
public void run()
{
for(int i=1;i<=3;i++)
CBank.add(100); //将100元分3次导入
}
}
//App3.java
public class App3 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CCustomer c1=new CCustomer();
CCustomer c2=new CCustomer();
c1.start();
c2.start();
}
}
//运行成果
sum=100
sum=200
sum=100
sum=300
sum=200
sum=300
运行成果与我们预想的600不一样。这是因为两个线程共享同一个变量,且此中一个线程在run()还没停止前,另一个线程已经开端启动了,是以造成策画上的错误。
要获得600,只要让第一个线程吹了完毕,接着再处理惩罚第二个线程即可,这就要用到同步处理惩罚了,即synchronized,在add()之前加上这个关键字,可以使得各线程在时候上取得调和,一次只容许一个线程进入run()进行处理惩罚,代码如下:
//CBank.java
public class CBank {
private static int sum=0;
public synchronized static void add(int n)
{
int tmp=sum;
tmp=tmp+n;
try {
Thread.sleep((int)(1000Math.random()));
}
catch(InterruptedException e) {}
sum=tmp;
System.out.println(sum=+sum);
}
}
//CCustomer.java
public class CCustomer extends Thread {//顾客类,持续自Thread类
public void run()
{
for(int i=1;i<=3;i++)
CBank.add(100); //将100元分3次导入
}
}
//App3.java
public class App3 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CCustomer c1=new CCustomer();
CCustomer c2=new CCustomer();
c1.start();
c2.start();
}
}
运行成果:
sum=100
sum=200
sum=300
sum=400
sum=500
sum=600
至此,多线程的进修临时到这里。。
读书,不要想着实用,更不要有功利心。读书只为了自身的修养。邂逅一本好书如同邂逅一位知己,邂逅一个完美之人。有时心生敬意,有时怦然心动。仿佛你心底埋藏多年的话,作者替你说了出来,你们在时光深处倾心相遇的一瞬间,情投意合,心旷神怡。
软件专业的大学生,立志成为法度媛,这学期才刚接触java,其实是够菜,高手们能指导一二,不堪感激感动。
今天学到了Java的多线程,下面是我做的笔记,仅供参考和复习。
- java的多线程:同时履行多个法度区块
- 启动线程:必须具备两个前提:
(1) 此类必须是延长自Thread类,使本身成为它的子类
(2) 线程的处理惩罚必须编写在run()办法中
注:Thread类存放在java.lang类库中,所以无需手动加载,调用start(),用以启动线程
3.实现Runnable接口来创建线程
因为Java不克不及多重持续,Java供给了Runnable接口,正好可以解决这个困难。接口中声明run()办法,只要在类中确切定义run()办法,就可以创建线程了。
下面是例子:
public class MyRunnable implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName());
//获得当前thread对象
然后在调用这个thread的 getName()办法。
}
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnable t1=new MyRunnable();
MyRunnable t2=new MyRunnable();
Thread th1=new Thread(t1,MyThread1);
Thread th2=new Thread(t2,MyThread2);
th1.start();
th2.start();
}
}
4.线程的经管
每一个线程,在其创建和灭亡之前,均会处于四种状况之一:新建的(newly created)、可运行的(runnable)、被冻结的(blocked)与灭亡的(dead);
当用new Thread()创建对象时,线程所处的便是这种状况,但此时体系并不会设备资料,直到用start()办法启动线程时才会设备;
当start()启动线程时,线程便进入可运行的状况,谁先抢到cpu,谁开端履行run()办法,其余的线程便在队列中守候机会争夺cpu资料;
当线程调用对象的wait() method 或该线程本身调用sleep(),冻结状况线程便产生。sleep(long millis)可用来设定睡眠的时候,millis毫秒(1/1000秒)。该线程和另一个线程join()在一路,则其他未启动的线程或法度代比及该线程停止后才会开端履行;
当线程被冻结时,便停止run()的履行,直到被冻结的身分消散,线程便回到可运行状况;
被冻结身分消散的原因可所以:
a,若是线程是用调用对象的wait()所冻结,则改对象的notify() 被调用时可解除冻结。(notify:告诉);
b,线程进入睡眠状况,但指定的时候到了。
当线程的run()履行停止,或调用了stop(),则线程进入灭亡状况。
举例:
1.若是要简单的设计线程的排序,可用join(),当某一线程调用join时,则其他线程会比及该线程停止后才开端履行,下面的例子,使得dog线程先完成后,再履行cat线程,比及线程履行停止后,再打印“Hello world;
//CTest.java
public class CTest extends Thread {
private String id;
public CTest(String str) {
id=str;
}
public void run() {
for(int i=0;i<4;i++)
{
try
{
sleep((int)(1000Math.random()));
}catch(InterruptedException e) {}
System.out.println(id+is running..);
}
}
}
//App2.java
public class App2 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CTest dog=new CTest(doggy);
CTest cat=new CTest(cat);
dog.start(); //启动dog线程
try
{
dog.join();//限制dog线程停止后才干往下履行
cat.start();//启动cat线程
cat.join(); //限制cat线程停止后才干往下履行
}
catch(InterruptedException e) {}
System.out.println(Hello World);
}
}
有没有重视到try...catch这段代码?这是因为,sleep()和join()必须写在try...catch里面,以捕获可能呈现的异常。
再来讲一下关于同步处理惩罚,先来举个例子: 假设有家银行,它可接管顾客的汇款,每做一次汇款,便可策画出汇款的总额,如今又两名顾客,每人分3次,每次100元将钱导入,最后银行汇款的总额应当为600元。
为解决这个题目,我们来写段代码:
//CBank.java
public class CBank {
private static int sum=0;
public static void add(int n)
{
int tmp=sum;
tmp=tmp+n;
try {
Thread.sleep((int)(1000Math.random()));
}
catch(InterruptedException e) {}
sum=tmp;
System.out.println(sum=+sum);
}
}
//CCustomer.java
public class CCustomer extends Thread {//顾客类,持续自Thread类
public void run()
{
for(int i=1;i<=3;i++)
CBank.add(100); //将100元分3次导入
}
}
//App3.java
public class App3 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CCustomer c1=new CCustomer();
CCustomer c2=new CCustomer();
c1.start();
c2.start();
}
}
//运行成果
sum=100
sum=200
sum=100
sum=300
sum=200
sum=300
运行成果与我们预想的600不一样。这是因为两个线程共享同一个变量,且此中一个线程在run()还没停止前,另一个线程已经开端启动了,是以造成策画上的错误。
要获得600,只要让第一个线程吹了完毕,接着再处理惩罚第二个线程即可,这就要用到同步处理惩罚了,即synchronized,在add()之前加上这个关键字,可以使得各线程在时候上取得调和,一次只容许一个线程进入run()进行处理惩罚,代码如下:
//CBank.java
public class CBank {
private static int sum=0;
public synchronized static void add(int n)
{
int tmp=sum;
tmp=tmp+n;
try {
Thread.sleep((int)(1000Math.random()));
}
catch(InterruptedException e) {}
sum=tmp;
System.out.println(sum=+sum);
}
}
//CCustomer.java
public class CCustomer extends Thread {//顾客类,持续自Thread类
public void run()
{
for(int i=1;i<=3;i++)
CBank.add(100); //将100元分3次导入
}
}
//App3.java
public class App3 {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
CCustomer c1=new CCustomer();
CCustomer c2=new CCustomer();
c1.start();
c2.start();
}
}
运行成果:
sum=100
sum=200
sum=300
sum=400
sum=500
sum=600
至此,多线程的进修临时到这里。。
读书,不要想着实用,更不要有功利心。读书只为了自身的修养。邂逅一本好书如同邂逅一位知己,邂逅一个完美之人。有时心生敬意,有时怦然心动。仿佛你心底埋藏多年的话,作者替你说了出来,你们在时光深处倾心相遇的一瞬间,情投意合,心旷神怡。