线程就是进程的儿子,没有了进程线程也( •̀ ω •́ )y就没有了,javascript没有线程的概念,但是有定时器(setTimeout),虽然没有java中名副其实的线程,但是也够用了;

  java要使用线程有两种方式, 第一种是直接让类继承Thread, 第二种是让类继承Runnable接口的方式, 推荐使用继承接口(Runable)的方式使用线程;

  第一种方式,使用extends继承Thread:

public class ThreadDemo0 extends Thread{
private String name;
public /*void*/ ThreadDemo0(String name) {
this.name = name;
};
public void run() {
for(int i=0; i<10; i++) {
System.out.println("THREAD: "+name+" run in thread " + i);
};
};

public static void main (String args[]) {
/*
new ThreadDemo0("hehe").run();
new ThreadDemo0("lala").run();
*/
new ThreadDemo0("hehe").start();
new ThreadDemo0("lala").start();
};
};

  这种方式继承好理解, 要注意的是如果new出的线程 new ThreadDemo0("hehe") , start一次以后,再start一次是会报异常的,

  所以我们每一次都要重新new这个类, 每一次都产生了新实例, 新实例跟上次实例化的实例一点关系都没有,我们无法简单地通过多线程同时做一件事情;

public class ThreadDemo0 extends Thread{
private String name;
private int arr[];
public /*void*/ ThreadDemo0(String name) {
this.name = name;
}
public void setArr (int arr[]) {
this.arr = arr;
}
public void run() {
for(int i=0; i<this.arr[0]; i++) {
System.out.println("THREAD: "+name+" run in thread " + i);
};
};

public static void main (String args[]) {
int sArr[] = {10};
ThreadDemo0 t0 = new ThreadDemo0("hehe");
ThreadDemo0 t1 = new ThreadDemo0("lala");
t1.setArr(sArr);
t0.setArr(sArr);
t1.start();
t0.start();
};
};

 

  Runnable跟Thread有点不同, Runnable相当于你运行的代码在多个线程里面是共享的, 这个才是真正的多线程哇

public class RunAndThread0 implements Runnable{
private int ticket = 5;
public RunAndThread0( ) {
}
public void run() {
while( true ) {
if( ticket>0 ) {
System.out.println("sell one; has tickets " + --ticket);
}else{
return ;
}
}
}
public static void main(String []args) {
RunAndThread0 run = new RunAndThread0();
//to use interface Runnable to share the variables;
new Thread(run).start();
new Thread(run).start();
}
}

  Runnable是实现的Thread的run接口, 最后再通过Thread启动线程;

  如果你不想共享作用域内的代码变量,你再重新实例化一个Runnable,重启一个线程, 这个效果跟extends Thread一样的:

public class RunnableDemo0 implements Runnable {
private String name;
public RunnableDemo0(String name) {
this.name = name;
}
public void run() {
for(int i=0; i<10; i++) {
System.out.println(name+" in thread " + i);
}
}
public static void main(String[] args) {
RunnableDemo0 hehe = new RunnableDemo0("hehe");
Thread tHehe = new Thread(hehe);
RunnableDemo0 lala = new RunnableDemo0("lala");
Thread tLala = new Thread(lala);

tHehe.start();
tLala.start();
}
}

  

  通过Thread.currentThread()可以获取当前的正在执行的线程, getName()可以获取线程的名字, 如果我们没有给线程起名字, 系统会为线程起名字,像这样的:

  Thread-0, Thread-1, Thread-2, Thread-3....

public class CurrentThread implements Runnable{
public void run( ) {
System.out.println( Thread.currentThread().getName() );
}
public static void main(String []args) {
CurrentThread ct = new CurrentThread();
Thread tCt = new Thread(ct);
tCt.start();
System.out.println(tCt.isAlive());
//this is main thread;
new CurrentThread().run();

System.out.println(tCt.isAlive());
System.out.println(tCt.isAlive());
System.out.println(tCt.isAlive());
}
}

 

  Thread.sleep,就是让线程睡觉去, 参数是毫秒, (1000毫秒为1秒),Thread.sleep要用tryCatch包裹起来,要么编译的时候会有提示,你不加,他还编译不过去(太矫情了,这个是为什么呢?):

java学习笔记6(线程)_System

public class ThreadSleep implements Runnable{
public void run() {
try{
Thread.sleep(5000);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("sleeping");
}
public static void main(String []args) {
new Thread( new ThreadSleep() ).start();
}
}

 

  线程的优先级Priority, 优先级越高的话, 线程越早开始跑,系统默认的优先级为5, 最低的为1, 最高的为10,通过setPriority设置到线程的实例:

public class ThreadPriority implements Runnable {
public void run( ) {
for( int i=0 ;i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " : " + Thread.currentThread().getPriority());
};
}
public static void main(String args[]) {
new Thread(new ThreadPriority()).start();
Thread t0 = new Thread(new ThreadPriority());
t0.setPriority(10);
t0.start();
Thread t1 = new Thread(new ThreadPriority());
t1.setPriority(1);
t1.start();
}
}

 

  线程的join方法, 就是把一个线程加在另一个线程后面运行的(排队上车, 你先上好了,我等等, 我就跟你后面):

public class ThreadJoin implements Runnable{
private Thread t;
public ThreadJoin() {}
public ThreadJoin( Thread t ) {
this.t = t;
}
public void run() {

for(int i=0 ; i<40; i++) {
try{
if(i>10&&t.isAlive()) {
t.join();
};
}catch( Exception e){
//e.printStackTrace();
}
System.out.println( "thread name"+ Thread.currentThread().getName() + " i = " + i );
}
}
public static void main(String [] args) {
Thread t0 = new Thread(new ThreadJoin());
t0.start();
Thread t1 = new Thread(new ThreadJoin(t0));
t1.start();

}
}

 

  如果一个线程同时操作一条数据,因为两个线程不是同步的,导致数据不同步, 就比如两个人抢银行, 一个人抢了30元, 一个人抢了40元,本来银行就只有40元钱, 银行跟两个盗窃者承诺了给钱 ,银行给了一个人40元, 又给了一个人30元, 发现自己亏了30元, 银行郁闷了:

public class ThreadSync implements Runnable{
private int ticket = 10;
public void run( ) {
while(true) {
if(ticket>0) {
try{
//we should to do someting , to sure users state;
Thread.sleep(1000);
}catch( Exception e) {
e.printStackTrace();
};

ticket--;
System.out.println("lev :" + ticket);
}else{
return;
}
}
}
public static void main(String [] args) {
ThreadSync ts = new ThreadSync();
Thread t0 = new Thread(ts);
Thread t1 = new Thread(ts);
Thread t2 = new Thread(ts);
Thread t3 = new Thread(ts);
t0.start();
t1.start();
t2.start();
t3.start();
}
}

  卖出去的票出问题, 坑爹地变成了负数, 然道让多出来的乘客站着吗。。。。多线程的问题

java学习笔记6(线程)_优先级_02

  如何解决这个问题呢,我们使用synchronized方法:

public class Sync implements Runnable{
private int ticket = 10;
public void run( ) {
while(true) {
synchronized( this ) {
if(ticket>0) {
try{
//we should to do someting , to sure users state;
Thread.sleep(1000);
}catch( Exception e) {
e.printStackTrace();
};
ticket--;
System.out.println("lev :" + ticket);
}else{
return;
}
}
}
}
public static void main(String [] args) {
Sync ts = new Sync();
Thread t0 = new Thread(ts);
Thread t1 = new Thread(ts);
Thread t2 = new Thread(ts);
Thread t3 = new Thread(ts);
t0.start();
t1.start();
t2.start();
t3.start();
}
}

 

java学习笔记6(线程)_i++_03

 

  或者使用synchronzed方法语句:

public class SyncB implements Runnable{
private int ticket = 10;
public void run( ) {
while(true) {
if( toRun() ) {
return ;
}
}
}
public synchronized boolean toRun( ) {
if(ticket>0) {
try{
//we should to do someting , to sure users state;
Thread.sleep(1000);
}catch( Exception e) {
e.printStackTrace();
};
ticket--;
System.out.println("lev :" + ticket);
return false;
}else{
return true;
}
}
public static void main(String [] args) {
Sync ts = new Sync();
Thread t0 = new Thread(ts);
Thread t1 = new Thread(ts);
Thread t2 = new Thread(ts);
Thread t3 = new Thread(ts);
t0.start();
t1.start();
t2.start();
t3.start();
}
}

  运行后的效果跟上面一模一样,就可以避免线程同时访问导致数据不对头的问题;

天道酬勤