线程的生命周期及状态转换:
新建(new),就绪(Runnable),运行(running),阻塞(blocked),死亡(Terminated)
新建:
Thread thread = new Thread();
或者:
Runnable r = new Runnable();
Thread thread = new Thread(r,"新线程");
就绪:
执行run()方法
阻塞:
1)程序试图获取某个对象的同步锁,而该锁被其他线程说持有---获取到其他线程所持有的锁
2)线程调用了一个阻碍式的io方法---io方法返回
3)线程调用了某个对象的wait()方法---notify()方法唤醒
4)线程调用了Thread的sleep(long millis)方法---等
5)一个线程中调用了另一个线程的join()方法---等
线程的调度:为程序中的线程分配cpu的使用权
分为:
分时调度模型
抢占式调度模型(默认)
线程的优先级:1-10
三个Thread的静态常量:
static int MAX_PRIORITY:10
static int MIN_PRIORITY:1
static int NORM_PRIORITY:5
setPriority(int newPriority)来设置优先级
Example07.java:
class MaxPriority implements Runnable {
public void run(){
for(int i = 0 ; i < 10 ; i++){
System.out.println(i);
}
}
}
class MinPriority implements Runnable {
public void run(){
for(int i = 0; i <10 ; i ++){
System.out.println(i);
}
}
}
class Example07 {
public void static main(String[] args){
MaxPriority maxPriority = new MaxPriority();
MinPriority minPriority = new MinPriority();
Thread t1 = new Thread(maxPriority,"高优先级线程");
Thread t2 = new Thread(minPriority,"低优先级线程");
t1.setPriority(MAX_PRIORITY);
t2.setPriority(MIN_PRIORITY);
t1.start();
t2.start();
}
}
线程让步:Thread.yield();
线程插队:jion();
线程休眠:sleep();
Example10.java---多线程以及线程的插队
public class Example10 {
public void stati main(String[] args){
EmergencyThread emergencyThread = new EmergencyThread();
Thread t = new Thread(emergencyThread , "插线程");
for(int i = 0 ; i <= 5 ; i ++){
System.out.println(Thread.currentThread().getName() + i)
if(i == 2 ){
t.join();
}
Thread.sleep(500);
}
}
}
class EmergencyThread implements Runnable {
public void run(){
for(int i = 0; i < 6 ; i ++) {
System.out.println(Thread.currentThread().getName() + i)
try{
Thread.sleep(500)
}catch{
}
}
}
}
多线程同步:
保证用于处理共享资源的代码在任何时刻只能有一个线程访问
格式:
synchronized(lock){
操作共享资源的代码
}
锁对象的创建代码不能放到run()方法中,要放外边,synchronized(lock){}放在run()方法内
Example12.java
class Ticket1 implements Runnable {
private int tickets = 10;
Object object = new Object();
public void run(){
while(true){
synchronized(lock){
try{
Thread.sleep(500);
}catch{}
if(tickets > 0){
System.out.println(Thread.currentThread().getName() + "---票号"+tickets--);
}else{
}
}
}
}
}
public class Example12{
public void static main(String[] args){
Ticket1 t1 = new Ticket();
Thread thread1 = new Thread(t1 , "线程1");
Thread thread2 = new Thread(t1 , "线程2");
Thread thread3 = new Thread(t1 , "线程3");
thread1.start();
thread2.start();
thread3.start();
}
}
同步方法也可以实现和synchronized(lock){}同样的效果
格式:
synchronized 返回值类型 方法名(参数){}
class Ticket1 implements Runnable {
int tickets = 10;
public void run(){
while(true){
saleTickets();
if(tickets <= 0){
break;
}
}
}
private synchrozied void saleTickets(){
if(tickets > 0) {
System.out.println(Thread.currentThread().getName() + "售出"+ tickets -- "张票");
}
}
}
public class Example13 {
public void main(String[] args){
Ticket1 t = new Ticket1();
new Thread(t , "线程1").start();
new Thread(t , "线程2").start();
new Thread(t , "线程3").start();
}
}
同步方法的锁就是当前调用该方法的对象,也就是this指向的对象。
静态同步方法的锁死该方法所在类的class对象
线程的通信:
thread.wait()
thread.notify()
thread.notifyAll()
没有线程之间的通信的情况下,会出现乱入问题
先写一个对象类:
class Storage{
//用于储存数据的数组
private int[] arr = new int[10];
//数组的角标
private int outIndex, inIndex;
//存数据
public void put(int num){
arr[inIndex] = num;
System.out.println("在arr["+inIndex+"]中存入数据“+arr[inIndex]);
inIndex ++;
if(inIndex > 10){
inIndex = 0
};
}
//取数据
public void get() {
int data = arr[outIndex];
System.out.println("从arr["+outIndex+"]中取出数据"+arr[outIndex]);
outIndex++;
if(outIndex == arr.length){
outIndex = 0;
};
}
}
再来线程类:
class Input implements Runnable {
Strorage s = new Strorage();
int num ;
//要写一个构造方法来接受一个storage对象
Input(Storage s ){
this.s = s ;
}
public void run(){
while(true){
s.put(num);
num ++;
}
}
}
class Get implements Runnable {
Strorage s = new Storage();
//要写一个构造方法来接受一个storage对象!
Get(Storage s){
this.s = s;
}
public void run(){
while(true){
s.get();
}
}
}
现在可以写测试方法了:
public class test{
public void static main(String[] args){
Storage st = new Storage();
Input input = new Input(st);
Output output = new Output(st);
new Thread(input).start();
new Thread(output).start();
}
}
这时会发现各线程比较混乱
解决问题的方法:
1)用count记录数量
2)用wait()和notify()
其实每个方法也只添加了4行代码
class Storage{
//new一个贮存空间
int[] arr = new int[10];
//用来记录数量的count
int count ;
int inIndex,outIndex;
public synchronized void put(int num){
while(count == 10){
this.wait();
}
arr[inIndex] = num;
inIndex ++;
if(inIndex == 10){
inIndex = 0;
}
count ++;
this.notify();
}
public synchronized void get(){
while(count == 0 ){
this.wait();
}
int data = arr[outIndex];
outIndex++;
if(outIndex == 10){
outIndex = 0;
}
count --;
this.notify();
}
|
|