java thread



1.what is thread

Threads are sometimes referred to as lightweight processes. Like processes, threads
are independent, concurrent paths of execution through a program, and each thread
has its own stack, its own program counter, and its own local variables. However,
threads within a process are less insulated from each other than separate processes
are. They share memory, file handles, and other per-process state.

2.use thread risky

When multiple threads access the same data item, such as a static field, an instance
field of a globally accessible object, or a shared collection, you need to make sure
that they coordinate their access to the data so that both see a consistent view of
the data and neither steps on the other's changes. The Java language provides two
keywords for this purpose: synchronized and volatile. We will explore the use and
meaning of these keywords later in this tutorial.

3.do not overdo thread(不要滥用thread)

因为thread是要消耗系统资源的,所以不要滥用thread。

4.例子

package j.threads;


/**
 * 
 * @author Administrator
 * 本程序建立了两个thread,一个用来计算素数;一个是主线程
 * 在主线程中创建了CalculatePrimes线程的实例,并且调用线程的start方法启动CalculatePrimes线程,
 * 接着主线程sleep了10秒钟,然后设置共享变量finished,从而停止CalculatePrimes线程的运行。
 * 
 *
 */
public class CalculatePrimes extends Thread {


public static final int MAX_PRIMES = 1000000;
public static final int TEN_SECONDS = 10000;

//共享数据,需要提供适当的限制,使得线程之间能看到共享数据的一致性。
public volatile boolean finished = false;


public void run() {
int[] primes = new int[MAX_PRIMES];
int count = 0;
for (int i = 2; count < MAX_PRIMES; i++) {
// Check to see if the timer has expired
if (finished) {
break;
}
boolean prime = true;
for (int j = 0; j < count; j++) {
if (i % primes[j] == 0) {
prime = false;
break;
}
}
if (prime) {
primes[count++] = i;
System.out.println("Found prime: " + i);
}
}
}


public static void main(String[] args) {
CalculatePrimes calculator = new CalculatePrimes();
calculator.start();
try {
Thread.sleep(TEN_SECONDS);
} catch (InterruptedException e) {
// fall through
}
calculator.finished = true;
}


}


section 2: thread的生命周期

1.创建thread的方式有两种

1.1继承Thread,覆盖run方法,new这个class的对象

1.2实现runable接口,覆run方法。

2.启动thread的方法和注意点

调用start方法启动线程,但是要注意不要再构造器中去启动线程,因为这个导致this逸出。

3.join方法
在一个线程中调用另一个线程对象的join方法,会导致调用者阻塞,直到被调用线程完成任务,调用线程才开始工作。
Thread.join() is generally used by programs that use threads to partition large
problems into smaller ones, giving each thread a piece of the problem. The example
at the end of this section creates ten threads, starts them, then uses Thread.join()
to wait for them all to complete.
例子如下:
package j.threads;


import java.util.Random;


/**
 * 
 * @author Administrator
 * 这个例子中共有11个活动的线程,主线程是main,在主线程中启动了10工作线程,
 * 之后主线程调用10个工作线程的join方法,使得主线程阻塞等待10个工作线程完成
 *
 * 工作线程task是在数组中寻找最大值。
 */
public class TenThreads {


private static class WorkerThread extends Thread {
int max = Integer.MIN_VALUE;
int[] ourArray;


public WorkerThread(int[] ourArray) {
this.ourArray = ourArray;
}


// Find the maximum value in our particular piece of the array
public void run() {
for (int i = 0; i < ourArray.length; i++)
max = Math.max(max, ourArray[i]);
}


public int getMax() {
return max;
}
}


public static void main(String[] args) {
WorkerThread[] threads = new WorkerThread[10];
int[][] bigMatrix = getBigHairyMatrix();
int max = Integer.MIN_VALUE;
// Give each thread a slice of the matrix to work with
for (int i = 0; i < 10; i++) {
threads[i] = new WorkerThread(bigMatrix[i]);
threads[i].start();
}
// Wait for each thread to finish
try {
for (int i = 0; i < 10; i++) {
threads[i].join();
max = Math.max(max, threads[i].getMax());
}
} catch (InterruptedException e) {
// fall through
}
System.out.println("Maximum value was " + max);
}


private static int[][] getBigHairyMatrix() {
int[][] matrix = new int[10][10];
try {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
matrix[i][j] = Random.class.newInstance().nextInt(100);
//System.out.println("matrix[" + i + "][" + j + "] = " + matrix[i][j]);
}
}
} catch (Exception e) {
}
return matrix;
}
}

4.对线程的调度

其实调用thread的join,wait,start都不能保证thread的这些方法马上执行,线程的执行是有os来调度的。所以我们不能根据程序中语句的先后来决定线程执行的先后顺序;所以对共享变量的访问必须提供必要的同步机制,使得共享数据对所有线程都是一致的。


Never
assume one thread will do something before another thread does, unless you've
used synchronization to force a specific ordering of execution.

package j.threads;

/**

这个程序一共有三个线程,主线程启动了Thread1和Thread2,程序中虽然对这两个线程的启动是有顺序的,但是输出结果可能有些例外

运行这个程序输出结果可能是:

•  1 2 A B
•  1 A 2 B
•  1 A B 2
•  A 1 2 B
•  A 1 B 2
•  A B 1 2

*/
public class TwoThreads {


// private int x;


public static class Thread1 extends Thread {
public void run() {
System.out.println("A");
System.out.println("B");
}
}


public static class Thread2 extends Thread {
public void run() {
System.out.println("1");
System.out.println("2");
}
}


public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}


}

5.thread的sleep方法和interrupt方法之间的交互


package j.threads;


/**
 * 
 * @author Administrator
 * 这个程序有2个线程,主线程确保启动了SleepInterrupt这个工作线程,
 * 在SleepInterrupt这个线程中sleep了20秒钟,在这个时间段中,SleepInterrupt
 * 让出占有的资源,以便主线程运行
 * 在主线程中调用了SleepInterrupt.interrupt()方法使得,SleepInterrupt catch到InterruptedException
 * 从而从sleep状态中醒来,执行未完成的工作。
 *
 * 主要调用Thread的sleep方法会持有lock,然后睡去。
 *
 */
public class SleepInterrupt extends Object implements Runnable {
public void run() {
try {
System.out.println("in run() - sleep for 20 seconds");
Thread.sleep(20000);
System.out.println("in run() - woke up");
} catch (InterruptedException x) {
System.out.println("in run() - interrupted while sleeping");
//return;
}
System.out.println("in run() - leaving normally");
}


public static void main(String[] args) {
SleepInterrupt si = new SleepInterrupt();
Thread t = new Thread(si);
t.start();


// Be sure that the new thread gets a chance to
// run for a while.
try {
Thread.sleep(2000);
} catch (InterruptedException x) {
}


System.out.println("in main() - interrupting other thread");
//在主线程中打断已经sleep 20秒的线程。
t.interrupt();
System.out.println("in main() - leaving");
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值