Java多线程
线程和进程的区别
可能也就是一个选择题
线程
在于并发concurrent
线程的生命周期
看图就好了
创建Java线程的方式
通过继承Thread方式实现
1.新建一个类,继承Thread类,这里叫作MyThread
2.完善run方法();执行代码在这里
3.新建MyThread实例
4.start()
class MyThread extends Thread //自定义线程类
{
public void run() //核心方法
{
System.out.println("MyThread线程执行");
}
}
public class test
{
public static void main(String []args)
{
MyThread myThread=new MyThread(); //创建实例
myThread.start(); //一定要用start,不可用run
}
通过实现Runnable接口
1.新建一个类,实现Runnable接口
2.重点在于实现run方法。
3.新建一个Runnable类实例
4.新建一个Thread类实例,初始化时传入实现了Runnable的类实例
5.start()
....
{
public static void main(String []args)
{
MyThread myThread=new MyThread();
Thread thread=new Thread(myThread); //将实现了Runnable的接口的类实例传过去
thread.start();
}
}
class MyThread implements Runnable //实现了Runnable接口
{
public void run()
{
System.out.println("线程运行");
}
}
几个跟线程生命周期相关的方法
yield:当前线程让出,当前线程进入就绪状态,等候重新获取
sleep:当前线程睡眠一段时间,进入阻塞状态,时间到了之后进入就绪状态
join:强制插入,使线程成为运行状态
重点:线程同步
PPT主要讲了synchronized方法。
synchronized
使用方法:
sychronized锁住某段代码块
sychronized锁住某个方法
通过对互斥锁的获取和释放,保证了只有一个线程拥有锁,
只有拥有锁的线程才能执行对应的程序
每个对象都可以作为互斥锁
一般用当前对象
程序执行完会自动释放锁
synchronized(Object ) //同步代码块
{
}
public synchronized int getNum() //同步方法,默认用当前类的实例对象作为锁
{
}
线程通信
wait
notify
notifyall
这个比较重实践
总结一下多线程的题目:
1.确定共享变量,尽可能的少 而足
2.定义共享变量(一些状态变量、一些锁)
3.定义一个实现了Runnable的类模板
4.通过参数设置不同的类实例(eg:abc、次数、下一个state)
5.开始start
**可以通过改变state,指定下一个code实现指定的任务启动**
实践
public class test {
public static volatile int state=0; //通过类的静态变量实现变量共享、并且是唯一变量
class printer implements Runnable
{ //内部类。主要是为了实现
private int printcode;
private int nextCode; //用于指示下一个状态量
private Object printLock; //锁元素
private int countNum;
private char printchar;
public printer(Object printLock, int countNum, int printcode, int nextCode, char printchar) //通过传入参数,实现不同实例要求
{
this.printchar = printchar;
this.printcode = printcode;
this.printLock = printLock;
this.countNum = countNum;
this.nextCode = nextCode;
}
public void run() { //运行方法
synchronized (printLock) { //同步代码段
for (int i = 0; i < countNum; i++) {
try {
if (printcode != test.state) {
printLock.wait();
}
else{
System.out.println(printchar);
test.state = nextCode;
printLock.notifyAll(); //一定要是notifyall
}
} catch (InterruptedException e) {
return;
}
}
}
} //内部类结束,内部类是为了能够简单的直接获取state共享变量
}
public void tst()
{
Object lock=new Object();
printer pa=new printer(lock,20,0,1,'a'); //各自的实例
printer pb=new printer(lock,20,1,2,'b');
printer pc=new printer(lock,20,2,0,'c');
Thread m1=new Thread(pa);
Thread m2=new Thread(pb);
Thread m3=new Thread(pc);
m1.start();
m2.start();
m3.start();
}
public static void main(String[]args) //外部类的main方法
{
test t=new test();
t.tst();
}
}
另外的一种实现方式是Java的锁lock
ReentrantLock和condition
不建议这么用 ,万一被老师判错
ReentrantLock是一个锁,可以实现跟 synchronized一样的封锁代码段的效果,
需要自己调用lock、unlock加锁解锁
ReentrantLock
方法:
lock() 加锁
unlock()解锁
newCondition() 通过锁产生条件,可以产生有多个条件
Condition
await() 等待,进入阻塞
sinal 通知一个线程解睡眠
sinalAll 通知所有线程解睡眠
// wait 模板,signal 模板
lock.lock();
try{
// wait 条件:一般都是使用while
while(meet the condition){
condition.await();
}
// 满足条件进行一系列操作
... your operation
otherCondition.signal()// otherCondition.signalAll()
}catch(){
}finally{
lock.unlock();
}
好吧,下面代码冗余太多了
import java.io.FileOutputStream;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class test
{
public static void main(String[]args) throws Exception
{
myThreaA a=new myThreaA();
myThreaB b=new myThreaB();
myThreaC c=new myThreaC();
a.start();
b.start();
c.start();
}
}
class Printer
{
static ReentrantLock lock=new ReentrantLock(); //共享量
static Condition c1=lock.newCondition();
static Condition c2=lock.newCondition();
static Condition c3=lock.newCondition();
private static volatile int state=0; //打印机状态
private int nowState; //实例的编号
private char nowChar; //对应实例的打印内容
Printer(int State,char c)
{
this.nowChar=c;
this.nowState=State;
}
public void printA() throws InterruptedException
{
lock.lock();
if (state!=nowState)
c1.await();
System.out.print('a');
state=(state+1)%3;
c2.signal();
lock.unlock();
}
public void printC() throws InterruptedException
{
lock.lock();
if (state!=nowState)
c3.await();
System.out.println('c');
state=(state+1)%3;
c1.signal();
lock.unlock();
}
public void printB() throws InterruptedException
{
lock.lock();
if (state!=nowState)
c2.await();
System.out.print('b');
state=(state+1)%3;
c3.signal();
lock.unlock();
}
}
class myThreaA extends Thread
{
Printer a=new Printer(0,'a');
public void run() {
for (int i = 0; i < 20; i++) {
try {
a.printA();
} catch (InterruptedException e) {
return;
}
}
}
}
class myThreaB extends Thread
{
Printer b=new Printer(1,'b');
public void run() {
for (int i = 0; i < 20; i++) {
try {
b.printB();
} catch (InterruptedException e) {
return;
}
}
}
}
class myThreaC extends Thread
{
Printer b=new Printer(2,'c');
public void run() {
for (int i = 0; i < 20; i++) {
try {
b.printC();
} catch (InterruptedException e) {
return;
}
}
}
}