MVC
MVC含義
一種軟件構架,簡單的說就是在做軟件的時候,可以將軟件分為不同的模塊,不同的模塊實現了不同功能。
MVC 組成部分
Model 模型
View 視圖
Controller 控制器
MVC就是三種組成部分的縮寫。
MVC 不同模塊的功能
Model(模型層) 程序員編寫程序應用的功能,數據庫設計等。屬于后臺操作。
View (視圖層) 前臺界面,也就是用戶可以看到的圖形見面,一般在web中是一些*.jsp或*.html。
Controller(控制器) 處理前臺和后臺請求。
MVC 優點
采用MVC的優點太多了,說再多不如你在真正的項目中自己體會,在這里不做太多解釋。
MVC 包結構

雖然,這并不能說明所有MVC框架所有的包模式,不過我覺得新手對于這個包結構還是比較容易接受的。
DAO 模式
在DAO層,最主要的作用是:完成數據的操作。在這層,你可以完成對任何表的數據操作,不過個人認為DAO層最大的作用是簡單了編程人員的編程邏輯,簡單的說就是將一個大的問題,分成了幾個比較小的問題,這樣不管在測試還是在維護都起著很大的方便。
Factory 工廠
Factory 工廠在這里也可以說成是DAO的工廠,這里Factory僅僅產生了DAO。那么Factory工廠模式有什么好處呢?
在MVC中的Factory 層,你完全可以把它想象成現實中的工廠,生產某些東西,如果在程序中使用工廠模式,你可以簡化編程代碼,相當與現實中你需要某個產品不需要自己去生產,完全可以去工廠“拿”一個,這樣程序的編程更加符合現實中的邏輯。
MVC 總結
本節,我僅僅是將MVC的編輯思想簡單的介紹了一下,我沒有加入一些詳細的例子,因為我覺得你在接觸MVC的時候,最好先了解MVC的編程思想,如果你要了解MVC的編程思想之后,你再接觸MVC的編程時,你就會覺得特別簡單。
最后,希望我這篇文章可以讓大家簡單的了解MVC的編程模式。
posted @
2011-01-25 09:30 tovep 閱讀(2168) |
評論 (9) |
編輯 收藏
摘要: ForEach小結
<c:forEach>標簽具有以下一些屬性:
var:迭代參數的名稱。在迭代體中可以使用...
閱讀全文
posted @
2011-01-24 08:37 tovep 閱讀(2360) |
評論 (0) |
編輯 收藏
通過以下Servlet程序和web.xml來說明web.xml的配置以及過程
創建一個Login的HTML文件
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>login.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<form action="
test1" method="
post">
<table border="0" width="379" height="79">
<tr>
<td>帳號:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="5" align="center"><input type="submit" value="登錄"></td>
</tr>
</table>
</form>
</body>
</html>
以上HTML標簽中要說明的是:
<form>標簽中的
action="test_Web_xml" 和 method="post" 分別定義了Html將登陸的信息發送給了誰,以及發送信息的方法!
創建一個Servlet程序
public class LoginServlet extends HttpServlet{
public void
doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = null;
username = request.getParameter("username");
String password = null;
password = request.getParameter("password");
if(username.equals("username")&&password.equals("password")){
request.getRequestDispatcher("成功登陸!!!").forward(request,response);
}else{
request.getRequestDispatcher("登陸失敗!!!").forward(request,response);
}
}
}
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>
Login
</servlet-name>
<servlet-class>
com.rise.LoginServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
Login
</servlet-name>
<url-pattern>
/test1
</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
我理解web.xml的作用就是將頁面和后臺程序正確連接!!!
通過一張圖片說明我理解的web.xml的作用
以上的內容是我自己對web.xml的理解,我覺得很簡單,但真正寫程序的時候部署程序是非常復雜的!
posted @
2010-12-11 20:43 tovep 閱讀(6300) |
評論 (2) |
編輯 收藏
什么是JDBC
JDBC是由一組Java語言編寫的類和接口組成,用來處理關系數據庫!利用JDBC的API,可用Java語法去訪問各種各樣的SQL數據庫。
個人認為:
把JDBC當做是一門連接Java程序連接數據庫的技術不如把JDBC當做連接程序和數據庫的橋梁。
以下我要寫的例子是用純Java的Driver來連接數據庫的方式。連接的數據庫是mysql。
JDBC編程步驟
1.加載數據庫驅動(jar文件)
//需要下載一個數據庫的jar包,并導入相應的JDBC項目中,創建路徑!
Class.forName("com.mysql.jdbc.Driver");
2.獲得數據庫連接
DriverManager.getConnection("jdbc:mysql://Database_IP:3306/DATABASE","DATAROOT","PASSWORD");//返回Connection————獲得數據庫連接
3.創建語句
String sql = "SQL_TORUNNING";
向DATABASE發送一個執行語句
Statement stmt = conn.createStatement();//創建一個 Statement 對象來將 SQL 語句發送到數據庫.
Statement—————SQL_RUNNING!!!
4.執行查詢
ResultSet rs = Statement.executeQuery(SQL_RUNNING);//執行SQL_RUNNING命令,返回ResultSet
//如果執行的數據庫語句不是對數據庫中的內容進行修改的話,則用 Statement.executeQuery()
//如果執行的數據庫語句是修改數據庫中的內容進行修改的話,則用 Statement.executeUpdate()
//當然他們返回值的類型也不同!
//根據命令的不同Statement的方法也不同
創建一個表
Statement.execute(create a table)
增刪改查Insert、update、delete...
Statement.executeUpdate()
查詢語句Select
Statement.executeQuery(Select);
5.遍歷結果集
while(ResultSet.next()){
ResultSet.getInt(int);
ResultSet.getString(int);
......
}
6.關閉數據庫連接
Connection.close();
步驟分析

(圖一)
1.加載數據庫驅動
我們來看圖一,工廠和幾個農村之間有一條河,不能夠直接進行溝通,工廠就相當于一個Java程序,而幾個農村就相當于不同的數據庫;
工廠為B村生產一些材料,但是生產出來之后并不能直接交給B村,然后工廠的廠長就想在工廠和B村之間架設一座橋梁來運送生產出來的材料——我們大可把數據庫驅動加載當做這個架設橋梁的想法。
在程序中我們要怎么做呢?
在加載數據庫驅動的時候,必須要將相應的mysql-connector-java-5.0.4-bin.jar包,然后將jar包導入相應的項目中如下圖

在mysql-connector-java-5.0.4-bin.jar右擊建立路徑,就相當于import的過程——我不確定這么說對不對,但我是這么理解的。
建立路徑后,你的項目將出現一個新的文件,如下圖

這樣的話,你就可以順利加載數據庫驅動,否則當你在運行的時候會出現找不到Driver.class的異常,也就是無法加載數據庫驅動。
Class.forName("com.mysql.jdbc.Driver");
2.獲得數據庫連接
既然廠長有想法和B村之間架設一座橋梁,那就要和B村商量一下啊!然后,廠長就要去河的對岸,那條河呢?就是在工廠和B村之間的那條河(這條河就相當于Database_IP),然后去找B村的村長(在這里要明白是B村的村長不是A村的,所以不能找錯了!!!),找到B村村長,“我要在工廠和B村之間建設一座橋,來運輸我們的東西”,下一步談的當然是條件了,工廠老板說“我要B村出資90%,剩下的由工廠出!!”村長當然不干了,這橋當然也就沒法建設了!!!所以只有當兩者都滿意的情況下才可以建設橋梁(比如,各處50%)其實談條件的過程就相當于驗證數據庫的"DATAROOT"和"PASSWORD"!!!只有兩者都正確的情況下才可以進行下一步的計劃——也就是建設橋梁!!!
在程序中的過程如下:
Connection conn = null;
conn = DriverManager.getConnection("jdbc:mysql://Database_IP:3306/DATABASE","DATAROOT","PASSWORD");
//返回Connection————獲得數據庫連接
3.創建語句
橋已經建好了,然后工廠要準備一些卡車來運輸生產的貨物,然后農村需要根據不同的貨物來處理這些貨物,有些貨物直接卸在B村就可以了,但有些貨物卸在B村之后,B村要做一些處理然后運回工廠!!!
這個過程在程序是怎么體現的呢?
String sql = "SQL_TORUNNING";
向DATABASE發送一個執行語句
Statement stmt = conn.createStatement();//創建一個 Statement 對象來將 SQL 語句發送到數據庫.
Statement—————SQL_RUNNING!!!
4.處理數據庫發送來的消息
如果工廠運輸到B村的貨物,只要B村的村長給工廠開一張條就行了;但也會有一些貨物需要運回工廠!!
在程序中:
ResultSet rs = Statement.executeQuery(SQL_RUNNING);//執行SQL_RUNNING命令,返回ResultSet
//如果執行的數據庫語句不是對數據庫中的內容進行修改的話,則用 Statement.executeQuery()——需要返回一些貨物
//如果執行的數據庫語句是修改數據庫中的內容進行修改的話,則用 Statement.executeUpdate()——開張條就行了
//當然他們返回值的類型也不同!
//根據命令的不同Statement的方法也不同
創建一個表
Statement.execute(create a table)
增刪改查Insert、update、delete...
Statement.executeUpdate()
查詢語句Select
Statement.executeQuery(Select);
5.處理數據庫傳回的內容
這個過程由工廠完成,如果是返回的一些貨物的話,工廠要做一些處理。
處理的過程:
while(ResultSet.next()){
ResultSet.getInt(int);
ResultSet.getString(int);
......
}
6.關閉數據庫
這樣的話,工廠和B村的交易就完成,在現實世界中工廠和B村之間的橋梁不會被拆除,因為建一座橋的代價很大,但在程序和數據庫之間架設一座橋梁簡直太簡單了,所以在這里我們要把這座橋梁拆除。
Connection.close();
簡單的舉了一個例子來說明數據庫和程序之間是怎么連接的,望對大家有所幫助。
posted @
2010-12-09 18:37 tovep 閱讀(1661) |
評論 (1) |
編輯 收藏
SQL語言是操作數據庫的基礎語言,對于不同的數據庫語言產品,SQL語言大多是通用的,本篇博客旨在介紹一些最常用的SQL語句。希望對大家能有所幫助。
注:
本文中的紅色字體黃色背景的內容為SQL語句!!
笨人也是菜鳥,如果我寫的有錯誤,大家一定要指出來啊!!!好了,廢話不說了,切入正題:
首先,使用
status查看MySQL當前的信息
1.使用
show databases;語句查看當前數據庫:
2.使用
create database DATABASE_NAME;語句來創建DATABASE_NAME數據庫
這樣,我們創建好了一個名字為database_name的數據庫。
注:數據庫語句對字母大小寫不敏感!
3.使用
use DATABASE_NAME;切換到使用DATABASE_NAME數據庫模式。
4.在database_name數據庫創建一個表:
create table if not exists table_name -- 如果表table_name不存在則創建
(id int primary key auto_increment, -- 創建int類型為主鍵,且自動增長
name varchar(200) not null, -- 創建字符類型的列,最大長度是200字節
age int(3), -- 創建int類型,長度為3個字節
sex varchar(2), -- 創建字符類型,長度是2個字節
salary float(11,2), -- 創建float類型的列,長度為2個字節
address varchar(50), -- 創建字符類型,長度為50個字節
birthday date -- 創建日期類型
);
這樣就創建好了一張表,可以用 describe 或則 desc來查看表的結構
describe table_name;
desc table_name;
這樣數據就創建好了一張表,我們可以用
show tables; 來查看數據庫中所有表

然后,我們就可以看見我們創建的表
====================================================================================
數據庫最具核心的用法——對數據庫表的數據的
增刪改查。
向表中增加數據(要了加入表的結構,看哪項可以為空)
insert table_name (name,age,sex) values ('tovep',22,'男');
向表中加入數據的時候,并不是要把所有的信息都要寫近期,只要表中結構設置為可以為空的都
可以不寫!!
id不用寫,因為它是自動增長的!
要想查看表中的內容,可以用select語句———為了說明下面的情況,我加入了多條信息
select * from table_name; -- 將table_name表中的所有數據都打印出來
select name from table_name; --查看所有人的名字
select * from table_name where id<5; --將表中id小于100的都打印出來
在使用select 語句查詢的時,常常用到別名
select t.name,t.id,t.age from table_name as t;
select 語句中的where表示查詢的條件
where中還可以使用like與"%"對字符類型的列進行模糊查詢
select * from table_name where name like 't%';
update語句:修改數據
update 表名 set 字段名 = '修改的值'
update table_name set name='tvoep1' where id>2;

刪除用
delete from 表名 where 判斷信息
delete from table_name where id=5;

這樣的話就刪除了id=5的信息
====================================================================================
使用drop 來刪除表或者數據庫
drop table table_name;
drop database database_name;
posted @
2010-12-06 11:04 tovep 閱讀(2308) |
評論 (2) |
編輯 收藏
經過一個多月的Java學習,我們慢慢深入了解了Java中的一些比較高級的方法!但這些方法在你調試的時候一定要慎重!!不要等待失去了整個硬盤,才后悔莫及!!! 如果你在編程的時候多長個心眼,這些小的錯誤是可以避免的!!!
下面我們來看一下一個讓人很崩潰的錯誤,這個錯誤讓我感到不可思議!!代碼如下:
import java.io.File;
public class KillBackServer {
public static void main(String[] args){
File f = new File("C:\\");
fun(f);
}
//定義一個靜態函數,用來實現對一盤文件的遍歷
public static void fun(File f)
{
if(f.isDirectory())
{
File file[] = f.listFiles();
try
{
for(int i = 0 ; i <file.length ; i++)
{
fun(file[i]);
}
}
catch(Exception e){}
}
else
{
if("我是病毒.exe".equals(f.getName()))
System.out.println(f);
//僅僅當程序找到"我是病毒.exe"的 時候才執行這一句代碼
//f.delete();
System.out.println("該病毒已被查殺");}
System.out.println(f.getPath() + "***********************");
}
}
}
大家一定要注意紅色字體的代碼!!!我之所以注釋了,就是怕直接復制我的代碼,然后運行……
如果這樣后果你是知道的……
本來這段代碼是用來掃描C盤,找到"我是病毒.exe"文件,并把它刪除,判斷一個文件名,用的是equals這是對的!!!
錯就錯在:if()判斷,大家都明白了吧!
希望大家以后不要因為犯了這個低級錯誤,而把自己的硬盤給了格了= = |||
其實,有很多方法可以避免這種錯誤!!!比如,你可以在f.delete(); 后面加上一句打印語句,這樣的話,在你測試的時候就會發現,原來if語句后面少一個大括號……
這個錯誤寫出來僅僅為了提醒大家規范的重要性!!!
posted @
2010-11-17 21:29 tovep 閱讀(2671) |
評論 (16) |
編輯 收藏
/**
* Robot類 :
*
* exec 函數聲明:
* public Process exec (String command) throws IOException ,參數及功能說明:
* command: 一條指定的系統命令
* 功能:在單獨的進程中執行指定的字符串命令
*
* keyPress 函數說明:
* public void keyPress(int keycode),參數及功能說明:
* keycode:要按下的鍵(例如,KeyEvent.VK_A)
* 功能:模擬按下指定鍵
*
* keyRelease 函數說明:
* public void keyRelease(int keycode),參數及功能說明:
* keycode:要釋放的鍵
* 功能:模擬釋放指定鍵
*
* @param tovep
*/
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class Exce {
public static void main(String[] args) {
try{
//創建自動操作類
Robot robot = new Robot();
/**
*
* 利用Runtime類運行Word程序的方法為:
* Runtime.getRuntime().exec("cmd /c start winword");
* 括號里的是系統命令
*
*/
//啟動記事本程序
Runtime.getRuntime().exec("cmd /c start notepad");
//延緩幾秒鐘,等待記事本程序啟動成功
robot.delay(3000);
//模擬按下"Ctrl + Space" 組合鍵,啟動輸入法
pressKeyWithCtrl(robot,KeyEvent.VK_SPACE);
//模擬隨機按下100個字母,輸入漢字
for(int i=0;i<100;i++){
pressKey(robot, (int) (Math.random()* 25) + 'A');
pressKey(robot,KeyEvent.VK_SPACE);
}
//延緩5秒鐘,一共觀察
robot.delay(5000);
//關閉記事本
//closeApplication(robot);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
//模擬按下鍵盤字符鍵
public static void pressKey(Robot robot, int keyvalue){
//模擬按下
robot.keyPress(keyvalue);
//模擬彈起
robot.keyRelease(keyvalue);
}
//模擬同時按下"Ctrl"鍵和字符鍵
public static void pressKeyWithCtrl(Robot robot, int keyvalue){
//模擬按下
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(keyvalue);
//模擬彈起
robot.keyPress(keyvalue);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
//模擬按下"Alt + F4"組合鍵,關閉當前應用程序
public static void closeApplication(Robot robot){
//模擬按下"Alt + F4"組合鍵
//模擬按下
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_F4);
//模擬彈起
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_F4);
//模擬按下"N",不保存文件退出記事本程序
//模擬按下
robot.keyPress(KeyEvent.VK_N);
//模擬彈起
robot.keyRelease(KeyEvent.VK_N);
}
}
posted @
2010-11-17 00:14 tovep 閱讀(5416) |
評論 (1) |
編輯 收藏
在Java中,Everything is Object!所以在文件中,要不例外!
在Java中,可以用File類來表示一個文件!!!(注意這里的文件可以是所有文件,包括文件夾)
下面的代碼表示一個文件:
public class Demo {
public static void main(String[] args){
File f = new File("e:\\file");
if(f.isDirectory()){
System.out.println(f.getPath());
}
}
}
運行結果是:

代碼中isDirectory()方法是判斷文件是文件夾還是一個文件(這里可能有點迷糊),也可以這么理解,我所說的文件夾就是一個目錄,
getPath()方法是打印文件(這里指的是file文件夾)的路徑!!!
看看下面的代碼還有注釋:
/**
*
* File.speparator的作用是判斷在不同的系統中斜杠的方向
*
* 在windows中斜杠的方向是向右斜的\\
* 在Linux 中斜杠的方向是向左斜的//
*
*
* File中createNewFile方法:
* 當且僅當不存在具有此抽象路徑名指定名稱的文件時,不可分地創建一個新的空文件。
* 檢查文件是否存在,若不存在則創建該文件,這是單個操作,對于其他所有可能影響該文件的文件系統活動來說,該操作是不可分的。
*
* 注:此方法不應該 用于文件鎖定,因為所得協議可能無法可靠地工作。應該使用 FileLock 機制替代。
*
*
*/
import java.io.File;
public class Demo01 {
public static void main(String[] args) throws Exception{
File f;
f = new File("e:" + File.separator + "file" + File.separator + "io.txt");
System.out.println(f.createNewFile());
}
}
===================================
運行結果是:
大家注意,如果你的直接復制這些代碼的話,可能會出現以下異常
看看大家都明白了吧! 系統找不到指定的文件,就是在e盤下新建一個file文件夾就可以啦!!!
下面代碼詳細的介紹了File類中的createNewFile()方法:
/**
*
* File中createNewFile方法:
* 當且僅當不存在具有此抽象路徑名指定名稱的文件時,不可分地創建一個新的空文件。
* 檢查文件是否存在,若不存在則創建該文件,這是單個操作,對于其他所有可能影響該文件的文件系統活動來說,該操作是不可分的。
*
* 注:此方法不應該 用于文件鎖定,因為所得協議可能無法可靠地工作。應該使用 FileLock 機制替代。
* 返回:是布爾型
*
*/
import java.io.File;
public class Demo02 {
public static void main(String[] args) throws Exception{
File f = new File("f:\\demo.txt");
System.out.println(f.createNewFile());
}
}
運行結果如下:
下面介紹一下File類中delete()方法,代碼如下:
/**
*
* 要操作一個文件,必須要找到這個文件
* 在Java中,只有File類能表示一個文件,所有用File表示一個文件
* File的屬性就是文件的路徑,虛擬機會根據File類的參數找到指定的文件
* 找到問及那后可以用File類的方法進行操作!
*
* delete()方法可以刪除一個文件或者一個整個文件夾(整個目錄),返回結果是布爾類型!!
*
* */
import java.io.File;
public class Demo11 {
public static void main(String[] args) {
File f = new File("f:\\demo.txt");
f.delete();
if(boo){
System.out.println("成功刪除文件");
}
}
}
這個程序運行的結果:
下面的代碼是介紹查看一個文件的目錄,以及判斷這個文件是否是文件夾,代碼如下:
/**
*
* File的一個方法File.getPath()
* 是將此抽象路徑名轉換為一個路徑名字符串。
*
* File的exists方法
* 是測試此抽象路徑名表示的文件或目錄是否存在。
*
*
* File的getParent()方法
* 是返回此抽象路徑名父目錄的路徑名字符串;如果此路徑名沒有指定父目錄,則返回 null
*
* */
import java.io.File;
public class Demo21 {
public static void main(String[] args) {
File f = new File("f:" + File.separator + "demo.txt");
System.out.println(f.getPath());
System.out.println(f.getParent());
if(f.exists()){
f.delete();
}
else{
try{
System.out.println(f.createNewFile());
}catch(Exception e){}
}
}
}
運行結果:
再看一個判斷目錄的方法:
/**
*
* File的一個方法File.getPath()
* 是將此抽象路徑名轉換為一個路徑名字符串。
*
* File的isDirectory()的方法
* 是測試此抽象路徑名表示的文件是否是一個目錄。
* 當且僅當此抽象路徑名表示的文件存在且 是一個目錄時,返回 true;否則返回 false。
*
*
* */
import java.io.File;
public class Demo51 {
public static void main(String[] args){
File f = new File("f:" + File.separator + "aa");
System.out.println(f.getPath());
System.out.println(f.isDirectory());
}
}
運行結果:
注意下一個代碼,可能對你很有幫助啊!!
/**
*
* File的list()方法可以:
* 返回一個字符串數組,
* 這些字符串指定此抽象路徑名表示的目錄中的文件和目錄。
*
* */
import java.io.File;
public class Demo61 {
public static void main(String[] args) {
File f = new File("f:\\book");
//使用list列出
//列出的只是一個名稱
String[] str = f.list();
for(int i=0;i<str.length;i++){
System.out.println(str[i]);
}
}
}
這個程序的運行結果是你目錄下的文件:
下面的程序 你可能會很感興趣!因為你想玩HK,或者你想給別人整個惡作劇,你必須要掃描下他的電腦,以下方法就實現了怎樣去掃描一個電腦里的所有文件(我的代碼選擇的是掃描C盤下的所有文件,如果你想掃描其他盤,只要把文件改一下就OK啦)
import java.io.File;
public class Demo81 {
public static void main(String[] args) {
String str = "C:\\";
File f = new File(str);
fun(f);
}
//要不斷列出,因為給出的File類對象可能是一個目錄
public static void fun(File f){
//判斷給定的路徑是否是目錄,如果是目錄在列出
if(f.isDirectory()){
File[] file = f.listFiles();
//再依次循環進行判斷
try{
for(int i = 0;i < file.length;i++){
//繼續把內容傳入到fun方法之中進行驗證
fun(file[i]);
}
}catch(Exception e){}
}
else{
System.out.println(f);
}
}
}
運行結果我就不貼出來了,因為C盤的文件太多啦!!!如果你想知道,自己把代碼帶下看看,你會很吃驚的!你會想原來掃描的原理這么簡單!!!
posted @
2010-11-07 23:05 tovep 閱讀(59655) |
評論 (2) |
編輯 收藏
Java線程類有兩種實現方式,第一種就是繼承Thread類,另一種是現實Runnable接口。這兩種實現方式的區別很大,下面就說一下它們之間到底有什么區別。
我們首先用第一種方式寫一個線程類:
代碼如下:
package Ticket;
public class Extends {
public static void main(String[] args){
//實例化進程并準備執行
new Thread(new MyThread(),"001窗口").start();
new Thread(new MyThread(),"001窗口").start();
new Thread(new MyThread(),"001窗口").start();
}
}
class MyThread extends Thread{
//定義一個變量
private int ticket = 10;
public void run(){
//這里之所以要循環300次,就是為了讓所有的 車票都賣出去!可能你會想,為什么不是30呢?
//嘿嘿。。。聰明的你肯定明白這個循環的次數為什么會多出票數很多?=====其實我開始也不知道!!! ==|||
for(int i=0;i<300;i++){
try {
//調用sell()方法
this.sell();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sell(){
if(ticket>0){
System.out.println(Thread.currentThread().getName() + " ===> 還剩下" + (ticket--) + "車票");
}
}
}
看看這個程序的運行結果你就明白為什么繼承Thread類實現線程類的一個弊端
------------------------------------------------
大家都發現了吧!輸出的結果和預想的不一樣!!!
我們來分析一下代碼,查看main函數:
new Thread(new MyThread(),"001窗口").start();
new Thread(new MyThread(),"001窗口").start();
new Thread(new MyThread(),"001窗口").start();
我們可以看出,實例化了三個MyThread類,這樣的話,private int ticket = 10;就運行了三次,所以ticket打印出來的 也就是30張;在這里注意一下并不是ticket賦值為30,而是ticket賦值為10,但賦值了三次!!!也就是現在有三個ticket!!!
這樣并不能實現資源共享!
我們知道我們利用多線程就是為了將多個線程去處理一個數據的集合!!! 他們是同時處理的!!!如果向上面的話,并沒有將數據的集合(ticket)進行共享,而是將每一個類都從新建了一個數據的集合,分別對自己的集合進行處理!!!!
如果想解決這個問題,其實也很簡單,不過如果當數據的類型和種類比較多的時候,這樣寫就太麻煩了!!!!
那實現Runnable接口的線程類可不可以呢!!???
下面來看一看:
代碼如下:
package IO;
public class Inter {
public static void main(String[] args){
//聲明并實例化一個MyThread01類
MyThread01 mt = new MyThread01();
new Thread(mt,"001窗口").start();
new Thread(mt,"002窗口").start();
new Thread(mt,"003窗口").start();
}
}
class MyThread01 implements Runnable{
private int ticket = 10;
public void run(){
for(int i=0;i<200;i++){
try {
this.sell();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sell(){
if(ticket>0){
System.out.println(Thread.currentThread().getName() + " ===> 還剩下" + (ticket--) + "車票");
}
}
}
---------------------------------------------
這段程序的運行結果:

看看這個結果是不是和自己想的一樣啊!!!這樣就可以了!!!用這個方法去創建一個線程類是不是可以達到資源共享啊!!!
其實啊!我看來,所謂的資源共享也就是將一個數據的集合讓多個線程去處理!!!
我們看一下代碼!!!
MyThread01 mt = new MyThread01();
new Thread(mt,"001窗口").start();
new Thread(mt,"002窗口").start();
new Thread(mt,"003窗口").start();
我們可以看出這個過程中,我們只聲明并實例化了一個MyThread01類,也就是說在這里過程中,給ticket進行了初始化!!!
但大家要注意的是:真正創建處理數據的線程是
new Thread(mt,"001窗口").start();
new Thread(mt,"002窗口").start();
new Thread(mt,"003窗口").start();
因此,這樣可以將一個ticket的數據集 由三個線程來處理!!!
這樣就是所謂的資源共享!!!
ok???
=====================================================================
總結一下這兩種方式的特點:
1.繼承Thread來創建線程類的方法,在繼承了Thread后,不能再繼承其他類,這樣靈活性就不如實現Runnable接口來創建線程類的方法了!!!
2.正如上面所說的使用實現Runnable接口來創建線程類的方法可以達到資源共享!!!(在這里說明一下:繼承Thread類來創建線程類的方法也可以實現資源共享,只不過比較麻煩!!!因此,在創建線程類的時候,應優先選擇實現Runnable接口來創建線程類的方法!!!)
posted @
2010-11-07 20:30 tovep 閱讀(5956) |
評論 (8) |
編輯 收藏