以前在学Java的时候,没有仔细研究过多线程,后来在工作中也很少碰到,现在再捡起来学习一下。什么是多线程,经常和进程比较容易混淆,当程序启动以后,就会产生一个进程,而一个进程下面会有多个线程同步或者异步执行。
实现多线程的两种方式,在Java中可以通过实现Runable接口和继承Thread类来实现。
继承方式:
public class MyThread {
public static void main(String[] args) {
TestThread testThread=new TestThread("test thread");
testThread.start();
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
}
}
}
class TestThread extends Thread{
public TestThread(String name){
super(name);
}
@Override
public void run() {
//每一个成员变量都有一个存储空间
int index=0;
for (; index < 10; index++) {
System.out.println(this.getName()+index);
}
}
}
1.继承thread
接口方式:
public static void main(String[] args) {
ThredInterface interface1=new ThredInterface();
try {
interface1.begin();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class Mythread2 implements Runnable{
int index=0;
private boolean flag=true;
@Override
public void run() {
//需要多线程运行的程序
//共享成员变量,所有线程都来改
for (index=0; index < 2000; index++) {
if(!flag)break;
System.out.println(Thread.currentThread().getName()+index);
}
}
public void stopThread(){
//释放资源
flag=false;
}
}
1.实现runable接口
区别:
成员变量,继承的方式,是每个线程的成员变量都有一个存储空间,而接口的方式是所有线程共享一个成员变量,交替执行。
开发中一般使用接口方式调用,因为如果使用了继承的方式,那么该类就不能继承其他类了,而实现接口,可以实现多个接口。
常用方法:
为线程设置名称
thread中构造方法的第一个参数是实现runable接口的类,第二个参数就是线程名称
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
获取线程名称:Thread.currentThread().getName()
线程调度:
th.join();// 一直不轮换,当前线程必须走完
th.yield();// 暂时等待,不参与这一次的抢占-->到runable状态
但是线程的调度不能只通过这两个方法来控制
sleep休眠
stop停止线程,不建议使用 不安全,自己写一个停止的方法释放资源,定义一个stop线程的方法释放资源。
线程的状态:Runable runing blocked
线程同步:使用synchronized,可以在方法声明的时候标记,也可以使用一个key来作为线程同步块
synchronized (this) {
Mythread2 m=new Mythread2();
Thread th=new Thread(m,"线程1");
//Thread th2=new Thread(m,"线程2");
th.start();
//th2.start();
while (true) {
if (m.index==1000) {
System.out.println("tingzhi");
th.stop(); //不安全
m.stopThread();
break;
}
}
}
死锁:同步的嵌套的时候,线程之间相互等待
解决:同步的原子性放大,会降低效率,兼顾同步和效率
死锁程序:
public static void main(String[] args) {
new TestLock().run();
}
public void run(){
LockThread lockThread=new LockThread();
new Thread(lockThread,"线程一").start();
new Thread(lockThread,"线程二").start();
}
class LockThread implements Runnable{
private Object k1=new Object();
private Object k2=new Object();
private boolean flag=true;
@Override
public void run() {
if (flag) {
flag=false;
synchronized (k1) {
System.out.println(Thread.currentThread().getName()+"k1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (k2) {
System.out.println(Thread.currentThread().getName()+"k2");
}
}
}else{
flag=true;
synchronized (k2) {
System.out.println(Thread.currentThread().getName()+"k2...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (k1) {
System.out.println(Thread.currentThread().getName()+"k1");
}
}
}
}
}