Java多執行緒學習之實現方式
阿新 • • 發佈:2019-01-14
一、實現多執行緒的方式
1.繼承Thread類
步驟:
A:自定義MyThread類繼承Thread類;
B:重寫run()方法,包含被執行緒執行的程式碼;
C:建立物件;
D:啟動執行緒
package thread; public class ThreadPriority extends Thread{ @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 100; i++){ System.out.println(getName()+"--"+i); } } }
package thread; public class ThreadPriorityDemo { public static void main(String[] args) { ThreadPriority tp1 = new ThreadPriority(); ThreadPriority tp2 = new ThreadPriority(); ThreadPriority tp3 = new ThreadPriority(); //設定執行緒優先順序,最大值為10,最小為1,預設為5 tp1.setPriority(10); tp2.setPriority(1); //start()方法啟用執行緒 tp1.start(); tp2.start(); tp3.start(); } }
2.實現Runnable介面
步驟:
A:自定義類MyRunnable實現Runnable介面;
B:重寫run()方法;
C:建立MyRunnable類的物件;
D:建立Thread類物件,把上一步建立的類物件當作構造引數
package thread; public class MyRunnable implements Runnable { @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 100; i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }
package thread;
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
t1.start();
t2.start();
}
}
二、多執行緒模擬出售電影票
1.使用同步解決執行緒安全問題
package thread;
public class SellTicket implements Runnable{
//定義100張票
private int tickets = 100;
//定義同一把鎖
private Object obj = new Object();
@Override
public void run() {
while(true){
//同步
synchronized (obj) {
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"張票");
}
}
}
}
}
package thread;
public class SellTicketDemo {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st,"視窗1");
Thread t2 = new Thread(st,"視窗2");
Thread t3 = new Thread(st,"視窗3");
t1.start();
t2.start();
t3.start();
}
}
還可以把同步程式碼塊寫成同步方法,這時鎖物件是這個方法--this。//synchronized (this)
package thread;
public class SellTicket implements Runnable{
//定義100張票
private int tickets = 100;
//定義同一把鎖
private Object obj = new Object();
@Override
public void run() {
while(true){
sellTicket();
}
}
private synchronized void sellTicket(){
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"張票");
}
}
}
當方法時靜態時,鎖物件是類的位元組碼檔案物件,即當前類的class檔案。 //synchronized(SellTicket.class)
package thread;
public class SellTicket implements Runnable{
//定義100張票
private static int tickets = 100;
//定義同一把鎖
private Object obj = new Object();
@Override
public void run() {
while(true){
sellTicket();
}
}
private static synchronized void sellTicket(){
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"張票");
}
}
}
2.使用lock解決執行緒安全問題
package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SellTicketLock implements Runnable{
private int tickets = 100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try{
lock.lock(); //加鎖
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"張票");
}
}finally{
lock.unlock();
}
}
}
}
package thread;
public class SellTicketDemo {
public static void main(String[] args) {
SellTicketLock st = new SellTicketLock();
Thread t1 = new Thread(st,"視窗1");
Thread t2 = new Thread(st,"視窗2");
Thread t3 = new Thread(st,"視窗3");
t1.start();
t2.start();
t3.start();
}
}
把不安全的list集合安全的使用:
List<String> list1 = new ArrayList<String>(); //執行緒不安全
List<String> list2 = Collections.synchronizedList(new ArrayList<String>()); //執行緒安全
三、生產者消費者之等待喚醒機制
package pv;
public class Student {
private String name;
private int age;
private boolean flag; //預設為false,若為true,則有資料
public synchronized void set(String name,int age){
//若果有資料,就等待
if(this.flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//設定資料
this.name = name;
this.age = age;
//修改標記
this.flag = true;
this.notify();
}
public synchronized void get(){
//如果沒有資料,就等待
if(!this.flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.name+"---"+this.age);
this.flag = false;
this.notify();
}
}
package pv;
public class Set implements Runnable{
private Student s;
private int x = 0;
public Set(Student s){
this.s = s ;
}
@Override
public void run() {
while(true){
if(x % 2 == 0){
s.set("yj", 23);
}else{
s.set("kryie", 25);
}
x++;
}
}
}
package pv;
public class Get implements Runnable{
private Student s;
public Get(Student s){
this.s = s ;
}
@Override
public void run() {
while(true){
s.get();
}
}
}
package pv;
public class StudentDemo {
public static void main(String[] args) {
//建立資源
Student s = new Student();
//設定資源、獲取資源
Set st = new Set(s);
Get gt = new Get(s);
//執行緒類
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt);
//啟動執行緒
t1.start();
t2.start();
}
}