从网上看了许多有关java多线程的讲解,也做笔记总结一下。
1.实现Runnable接口相比于继承Thread类:
(1)适合多个相同的程序代码的线程去处理同一个资源
(2)可以避免java中的单继承的限制
(3)代码可以被多个线程共享,代码和数据独立
public class Test {
public static void main(String[] args) {
for(int i=0;i<5;i++){
Thread t = new MThread();
t.start();
}
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
R r = new R();
for(int i=0;i<5;i++){
Thread t = new Thread(r);
t.start();
}
}
}
class MThread extends Thread{
public int x = 0;
public void run() {
System.out.print(++x);
}
}
class R implements Runnable{
private int x = 0;
public void run() {
System.out.print(++x);
}
}
执行结果:1111112345
2.main方法也是一个线程。在java中所有的线程都是同时启动的,而什么时候哪个线程先执行,取决于CPU的资源。
在java中,每次程序至少启动2个线程,一个是main线程,一个是垃圾收集线程。因为使用java命令执行一个类时,实际上都会启动一个JVM,每个JVM其实就是在操作系统中启动了一个进程。
3.线程的强制执行:
public class A implements Runnable {
public void run() {
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
A a = new A();
Thread t = new Thread(a);
t.start();
for(int i=0;i<5;i++){
if(i>3){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main thread execute-->"+i);
}
}
}
执行结果:当i>3时,若线程Thread-0为执行完,则强制执行线程Thread-0
main thread execute-->0
main thread execute-->1
main thread execute-->2
Thread-0
main thread execute-->3
Thread-0
Thread-0
main thread execute-->4
3.线程的中断
public class B implements Runnable {
public void run() {
System.out.println("execute run()");
try{
Thread.sleep(10000);
System.out.println("thread finish sleep");
}catch (InterruptedException e){
System.out.println("thread interrupted");
return;
}
System.out.println("thread end");
}
public static void main(String[] args) {
B b = new B();
Thread t = new Thread(b);
t.start();
try{
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
t.interrupt();
}
}
执行结果:execute run()
thread interrupted
4.线程的优先级:并非优先级越高就先执行。谁先执行取决于谁先取得CPU资源。所以setPriority不一定起作用的,在不同的操作系统不同的jvm上效果也可能不同。操作系统也不能保证设置了优先级的线程就一定会先运行或得到更多的CPU时间。
public class C implements Runnable {
@Override
public void run() {
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()+" execute" + i);
}
}
public static void main(String[] args) {
Thread a = new Thread(new C(), "A");
Thread b = new Thread(new C(), "B");
Thread c = new Thread(new C(), "C");
a.setPriority(3);
b.setPriority(1);
c.setPriority(2);
a.start();
b.start();
c.start();
}
}
执行结果:
C execute0
B execute0
A execute0
B execute1
C execute1
B execute2
A execute1
C execute2
A execute2
5.线程的礼让:使用yield(),将一个线程的操作暂时交给其他线程执行
public class D implements Runnable {
@Override
public void run() {
for(int i=0;i<5;++i){
System.out.println(Thread.currentThread().getName()+" execute "+i);
if(i==3){
System.out.println(Thread.currentThread().getName()+" thread 礼让");
Thread.currentThread().yield();
}
}
}
public static void main(String[] args) {
Thread a = new Thread(new D(), "a");
Thread b = new Thread(new D(), "b");
a.start();
b.start();
}
}
执行结果:当a线程执行了yield(),若b线程尚未执行完毕,即交给b线程执行。
b execute 0
a execute 0
b execute 1
a execute 1
b execute 2
a execute 2
b execute 3
a execute 3
b thread 礼让
a thread 礼让
b execute 4
a execute 4
6.同步(同步代码块和同步方法)
同步代码块:
public class E implements Runnable {
private int count=5;
@Override
public void run() {
for (int i=0;i<10;i++){
synchronized (this){
if(count>0){
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+","+count--);
}
}
}
}
public static void main(String[] args) {
E e = new E();
Thread a = new Thread(e,"a");
Thread b = new Thread(e,"b");
Thread c = new Thread(e,"c");
a.start();
b.start();
c.start();
}
}
同步方法:
public class E implements Runnable {
private int count=5;
@Override
public void run() {
for (int i=0;i<10;i++){
sale();
}
}
public synchronized void sale(){
if(count>0){
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+","+count--);
}
}
public static void main(String[] args) {
E e = new E();
Thread a = new Thread(e,"a");
Thread b = new Thread(e,"b");
Thread c = new Thread(e,"c");
a.start();
b.start();
c.start();
}
}
执行结果:由于a,b,c三个线程都是用的e对象锁,所以a执行时,b,c等待
a,5
a,4
a,3
a,2
a,1
7.生产者消费者问题
public class G {
public static void main(String[] args) {
Info info = new Info();
Producer p = new Producer(info);
Consumer c = new Consumer(info);
new Thread(p,"p").start();
new Thread(c,"c").start();
}
}
class Info{
private boolean flag = false;
private String name="aa";
private int age = 10;
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
public synchronized void set(String name, int age){
if(!flag){
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
this.age = age;
flag = false;
super.notify();
}
public synchronized void get(){
if(flag){
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getName()+"--"+this.getAge());
flag = true;
super.notify();
}
}
class Producer implements Runnable{
private Info info = null;
Producer(Info info){
this.info = info;
}
public void run() {
boolean flag = false;
for(int i=0;i<5;++i){
if(flag){
this.info.set("aa", 10);
flag = false;
}else{
this.info.set("zz", 99);
flag = true;
}
}
}
}
class Consumer implements Runnable{
private Info info = null;
Consumer(Info info){
this.info = info;
}
public void run() {
for(int i=0;i<5;++i){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.get();
}
}
}
执行结果:
aa--10
zz--99
aa--10
zz--99
aa--10