=========================================基础概念=============================================
线程:是一个进程里边的不同执行路径。
主线程是main方法。
在一个时间点上一个单核CPU只支持一个线程执行。
用到的类 java.lang.Thread
VM启动时会有一个由主方法(public static void main(){})所定义的线程。
========================================实现方式===========================================
可通过创建Thread的实例来创建新线程,每个线程都是通过Thread对象所对应的方法run()来完成其操作,称为线程体。
1、定义实现了Runnable接口的类(例Runner)
2、在类中定义run方法
3、在主线程中定义Runner的对象(例r)
4、创建Thread的对象,构造参数为r。
5、调用Thread对象的start()方法启动线程。
package testThread1;
public class TestThread1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Runner1 r=new Runner1();
Thread t=new Thread(r);
t.start();
for(int i=0;i<50;i++) {
System.out.println("Main Thread: "+i);
}
}
}
class Runner1 implements Runnable{
@Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println("Runner1: "+i);
}
}
}
也可通过继承Thread类,然后创建对象调用 start()方法来启动一个线程。
package testThread1;
public class TestThread1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Runner1 r=new Runner1();
r.start();
//Thread t=new Thread(r);
//t.start();
for(int i=0;i<50;i++) {
System.out.println("Main Thread: "+i);
}
}
}
//class Runner1 implements Runnable{
class Runner1 extends Thread{
@Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println("Runner1: "+i);
}
}
最好使用接口来实现thread,比较灵活,实现接口的同时还可继承其他类。
=========================================================================================
线程状态转换
===========================================================================================
线程控制基本方法
=======================================sleep&interrupt========================================
package testInterrupt;
import java.util.Date;
public class TestInterrupt {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread mt=new MyThread();
mt.start();
try {
Thread.sleep(10000);
}catch(InterruptedException e) {}
mt.interrupt();
}
}
class MyThread extends Thread{
public void run() {
while(true) {
System.out.println("======"+ new Date()+"=======");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
return;
}
}
}
}
======================================join=================================================
package testJoin;
public class TestJoin {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread2 t1=new MyThread2("abcde");
t1.start();
try {
t1.join();
}catch(InterruptedException e) {}
for(int i=1;i<=10;i++) {
System.out.println("i am main thread");
}
}
}
class MyThread2 extends Thread{
MyThread2(String s){
super(s);
}
public void run() {
for(int i=1;i<=10;i++) {
System.out.println("i am "+getName());
try {
sleep(1000);
}catch(InterruptedException e) {
return;
}
}
}
}
====================================线程的优先级===============================================
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5.
Thread.MIN_PRIORITY=1
Thread.MAX_PRIORITY=10
Thread.NORM_PRIORITY=5
使用下述方法获得或设置线程对象的优先级
int getPriority();
void setPriority(int newPriority);
=====================================线程同步========================================
package testSync;
public class TestSync implements Runnable {
Timer timer=new Timer();
public static void main(String[] args) {
// TODO Auto-generated method stub
TestSync test=new TestSync();
Thread t1=new Thread(test);
Thread t2=new Thread(test);
t1.start();
t2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
timer.add(Thread.currentThread().getName());
}
}
class Timer{
private static int num=0;
public void add(String name) {
num++;
try {
Thread.sleep(1);
}catch(InterruptedException e) {}
System.out.println(name+", 你是第"+num+"个使用time的线程");
}
}
输出:
Thread-1, 你是第2个使用time的线程
Thread-0, 你是第2个使用time的线程
---------------------------------------------------------------------------------------------------------------
修改:添加互斥锁
package testSync;
public class TestSync implements Runnable {
Timer timer=new Timer();
public static void main(String[] args) {
// TODO Auto-generated method stub
TestSync test=new TestSync();
Thread t1=new Thread(test);
Thread t2=new Thread(test);
t1.start();
t2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
timer.add(Thread.currentThread().getName());
}
}
class Timer{
private static int num=0;
public synchronized void add(String name) {
//synchronized(this) {
num++;
try {
Thread.sleep(1);
}catch(InterruptedException e) {}
System.out.println(name+", 你是第"+num+"个使用time的线程");
//}
}
}
输出
Thread-0, 你是第1个使用time的线程
Thread-1, 你是第2个使用time的线程
-------------------------------------------------------死锁问题----------------------------------------------------------------
出现的情况:两个线程都拥有对方所需要的资源时产生死锁。
哲学家吃饭问题。
解决方法:可将锁的粒度加大
package testDeadLock;
public class TestDeadLock implements Runnable {
public int flag =1;
static Object o1=new Object(),o2=new Object();
public void run() {
System.out.print("flag="+flag);
if(flag==1) {
synchronized(o1){
try {
Thread.sleep(500);
}catch(Exception e) {
e.printStackTrace();
}
synchronized(o2){
System.out.println("1");
}
}
}
if(flag==0) {
synchronized(o2){
try {
Thread.sleep(500);
}catch(Exception e) {
e.printStackTrace();
}
synchronized(o1){
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestDeadLock td1=new TestDeadLock();
TestDeadLock td2=new TestDeadLock();
td1.flag=1;
td2.flag=0;
Thread t1=new Thread(td1);
Thread t2=new Thread(td2);
t1.start();
t2.start();
}
}
========================生产者消费者问题====================================================
package producerConsumer;
public class ProducerConsumer {
public static void main(String[] args) {
// TODO Auto-generated method stub
SyncStack ss=new SyncStack();
Producer p=new Producer(ss);
Consumer c=new Consumer(ss);
new Thread(p).start();
new Thread(p).start();
new Thread(p).start();
new Thread(c).start();
}
}
//生产和消费的实物
class WoTou{
int id;
WoTou(int id){
this.id=id;
}
public String toString() {
return "WoTou : "+id;
}
}
//存放实物的筐
class SyncStack{
int index=0;
WoTou[] arrWT=new WoTou[6];
public synchronized void push(WoTou wt) {
while(index==arrWT.length) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index]=wt;
index++;
}
public synchronized WoTou pop() {
while(index==0) {
try {
this.wait(); //当无实物时进入wait
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notifyAll(); //唤醒wait线程
index--;
return arrWT[index];
}
}
//生产者
class Producer implements Runnable{
SyncStack ss=null;
Producer(SyncStack ss){
this.ss=ss;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<20;i++) {
WoTou wt=new WoTou(i);
ss.push(wt);
System.out.println("生产了:"+wt);
try {
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable{
SyncStack ss=null;
Consumer(SyncStack ss){
this.ss=ss;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<20;i++) {
WoTou wt=ss.pop();
System.out.println("消费了: "+wt);
try {
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}