本章的要点
1.线程的启动
2.如何使线程暂停
3.如何使线程停止
4.线程的优先级
5.线程安全相关问题
进程
进程是操作系统结构的基础,是一次程序的执行。是一个程序及其数据在处理机上顺序执行时发生的活动,是程序在一个数据集合上运行的过程,它是系统资源分配和调度的一个独立单位。
实现多线程有两种方式:1.一种是继承Thread类,另一种是实现Runnable接口。
1.继承Thread类
public class MyThread extends Thread{
/**
* 继承并重写run接口
*/
@Override
public void run(){
super.run();
System.out.println("MyThread");
}
}
public class MyThreadTest {
public static void main(String[] args){
MyThread myThread = new MyThread();
myThread.start();//执行多线程myThread,实际运行的是MyThread的run方法
//myThread.start();多次start时,报Exception in thread "main" MyThread java.lang.IllegalThreadStateException错误
/**
* 打印MyThread,然后打印运行结束
* 这可以说明代码的运行结果与代码执行或者调用顺序是无关的。
*/
System.out.println("运行结束");
}
}
运行结果:打印MyThread,然后打印运行结束,这可以说明代码的运行结果与代码执行或者调用顺序是无关的。
2.实现Runnable接口
/*
1。实现多线程的另一种方式,实现接口
*/
public class Myrunnable implements Runnable {
@Override
public void run() {
System.out.println("运行中。。。。");
}
}
public class MyrunnableTest {
public static void main(String[] args){
Runnable runnable = new Myrunnable();
Thread thread = new Thread(runnable);
thread.start();
System.out.println("运行结束");
//运行结果:1。运行结束 2。运行中。。。。
}
}
运行结果:1。运行结束 2。运行中。。。。
进程
- 线程不共享数据
public class noShareThread extends Thread {
private int count = 5;
public noShareThread(String name){
super();
this.setName(name);//设置线程名
}
@Override
public void run() {
super.run();
/**
* 每个线程都有各自的变量count,count变量不共享。
*/
while (count > 0){
count--;
System.out.println("由" + this.currentThread().getName()
+ "计算,count" + count);
}
}
}
public class noShareThreadTest {
public static void main(String[] args){
noShareThread a = new noShareThread("A");
noShareThread b = new noShareThread("B");
noShareThread c = new noShareThread("C");
a.start();
b.start();
c.start();
}
}
运行结果:
由A计算,count4
由A计算,count3
由A计算,count2
由A计算,count1
由A计算,count0
由B计算,count4
由B计算,count3
由B计算,count2
由B计算,count1
由B计算,count0
由C计算,count4
由C计算,count3
由C计算,count2
由C计算,count1
由C计算,count0
- 线程数据共享
public class randomThread extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0 ; i < 10 ;i++){
int time = (int)(Math.random() * 1000);
Thread.sleep(time);
System.out.println("run=" + Thread.currentThread().getName());
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class yesShareThreadTest {
public static void main(String[] args){
yesshareThread shareThread = new yesshareThread();
Thread a = new Thread(shareThread,"A");
Thread b = new Thread(shareThread,"B");
Thread c = new Thread(shareThread,"C");
Thread d = new Thread(shareThread,"D");
Thread e = new Thread(shareThread,"E");
a.start();
b.start();
c.start();
d.start();
e.start();
}
}
运行结果*
由B计算,count=3
由A计算,count=3
由C计算,count=2
由D计算,count=1
由E计算,count=0
从运行结果中可以看到,线程A和线程B的count值为3,因为A和B同时对count进行操作,产生线程不安全的操作。在run方法前面加上synchronized关键字,给run方法上锁。
public class yesshareThread extends Thread {
private int count = 5;
@Override
synchronized public void run() {
super.run();
/**
* 不要用循环语句,因为是共享的数据,要让其他的线程也能多count进行操作
*/
count--;
//currentThread()返回代码段正在被哪个线程调用的信息。
System.out.println("由" + this.currentThread().getName()
+ "计算,count=" + count);
}
}
再次运行结果*
由A计算,count=4
由B计算,count=3
由C计算,count=2
由D计算,count=1
由E计算,count=0
非线程安全主要是指多个线程中的同一个实例变量进行操作时会出现值被修改,值不同步的情况,进而影响程序的执行流程。
相关函数
- currentThread()返回代码段正在被哪个线程调用的信息。
- isAlive()方法判断当前的线程是否属于活动的状态。活动状态就是线程已经启动且尚未终止,线程处于正在运行或者开始运行的状态。
- sleep()在指定的毫秒数内让当前"正在执行的线程"休眠(暂停执行)。
- getId方法的作用是取得线程的唯一标识,获得线程的名称和id值。